#include "stdafx.h" #include "TDbColumn.h" #include "TDbWallPatch.h" #include "OpeningLabelData.h" #include //T20 扩展数据定义 wlw add 150415 #define sKEY_OP_PROWIN_LINE _T("T20d1") // 用来标记是否是pc构件增加凸窗 #define OP_QUANTUM_1 _T("周长") #define OP_QUANTUM_2 _T("面积") #define OP_QUANTUM_3 _T("宽度") #define OP_HWINDOW 6 #define OP_HARCWIN 7 #define TDBOPENING_INSULATE _T("TDBOPENING_INSULATE") extern AcDbObjectId GetValidTextStyle(AcDbDatabase *pDb, const TCHAR *pStyle); extern void RemoveContainership(class TDbWall *pWall, class TDbOpening *pOpening); //extern void GemCreateExplodeBlock(AcDbVoidPtrArray& entityArray,AcDbVoidPtrArray& entitySet,AcGePoint3d ip,TCHAR *Layer); extern int GetViewDrawMode(); //extern int ExplodeBlockRef(AcDbBlockTableRecord &blockRec, ads_matrix matForInsert, DList &entSet); extern TARCH_IMPEXP void GetWinWidthModel(DList &lstWidth); extern TARCH_IMPEXP void GetDoorWidthModel(DList &lstWidth); extern TARCH_IMPEXP double GetModelNumber(DList &lstModel, double nNearNumber); //extern AcDbObjectId GetPrepickEntity(RBList &rbBaseMask); //Acad::ErrorStatus ConvertToDouble(const VARIANT *val, double *pRes); //Acad::ErrorStatus ConvertToInteger(const VARIANT *val, int *pInt); static AcDbObjectId g_idCurStretchOpening; //extern BOOL g_bMakeBlock; //extern double g_nAcadVer; extern double g_fWinLabelDefaultHeight; extern BOOL g_bSlotInsulateCap; extern double g_dSlotInsulateThick; // 1-TArch5;2-TArch6;3-TArch7;4-TArch8;5-TArch9 // const Adesk::UInt8 TDbOpening::g_nVersion = 4; const Adesk::UInt8 TDbOpening::g_nVersion = 5; ACRX_DXF_DEFINE_MEMBERS(ATSOpening, ATSEntity, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, 1, ATS_OPENING, "ATS_OPENING图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com"); IMPLEMENT_TENTBASE(TDbOpening); TDbOpening::TDbOpening() :m_uFrame(_AS_SYS_UNIT(40.0)), m_vFrame(_AS_SYS_UNIT(40.0)), m_nSlabThickness(_AS_SYS_UNIT(100.0)), m_nTextHeight(g_fWinLabelDefaultHeight) { m_colorText=7; m_iEnFlag=0; m_dbAbsorption=0; m_dbShadeCo=0; m_dbOutShadeCoSum=0; m_dbOutShadeCoWin=0; // 修改人 : lfy 2009-11-08 动态举证单位化 m_mat3d.setToIdentity(); // wlw add 门窗保温参数2011-02-15 m_nMaterial = GetSlotMaterial(); m_bSlotInsCap = g_bSlotInsulateCap; m_dInsWidth = g_dSlotInsulateThick; } // 用所在的 TDbOpening::TDbOpening(AcDbObjectId idWall, AcDbObjectId idStyle2d, AcDbObjectId idStyle3d) :m_uFrame(_AS_SYS_UNIT(40.0)), m_vFrame(_AS_SYS_UNIT(40.0)), m_nSlabThickness(_AS_SYS_UNIT(100.0)), m_nTextHeight(g_fWinLabelDefaultHeight) { m_nIdOfWall=idWall; m_nIdStyle2d=idStyle2d; m_nIdStyle3d=idStyle3d; m_colorText=7; m_iEnFlag=0; m_dbAbsorption=0; m_dbShadeCo=0; m_dbOutShadeCoSum=0; m_dbOutShadeCoWin=0; // 修改人 : lfy 2009-11-08 动态举证单位化 m_mat3d.setToIdentity(); // wlw add 门窗保温参数2011-02-15 m_nMaterial = GetSlotMaterial(); m_bSlotInsCap = g_bSlotInsulateCap; m_dInsWidth = g_dSlotInsulateThick; } // sg modify 110224,增加返回标注,告诉用户端是否需要补充数字 // CString TDbOpening::GetAutoLabel()const CString TDbOpening::GetAutoLabel(bool &bAddNum)const { TOpeningData::OpeningKind opKind; double nWidth, nHeight; opKind = GetKind(); nWidth = GetWidth(); nHeight = GetHeight(); // 获得门窗类别,以及软件内部固定死的标注前缀 CString csSectionLabel, csFixupLabel; if (opKind == TOpeningData::OP_DOOR) { csSectionLabel = _T("Door"); csFixupLabel = _T("M"); } else if (opKind == TOpeningData::OP_WINDOW) { csSectionLabel = _T("Window"); csFixupLabel = _T("C"); } else if (opKind == TOpeningData::OP_HOLE) { csSectionLabel = _T("Hole"); csFixupLabel = _T("DK"); } else if (opKind == TOpeningData::OP_ARCWIN) { csSectionLabel = _T("ArcWin"); csFixupLabel = _T("HC"); } else if (opKind == TOpeningData::OP_PROWIN) { csSectionLabel = _T("BayWin"); csFixupLabel = _T("TC"); } else if (opKind == TOpeningData::OP_CORNWIN) { csSectionLabel = _T("CornerWin"); csFixupLabel = _T("JC"); } else if (opKind == TOpeningData::OP_DOORWIN) { csSectionLabel = _T("DoorWin"); csFixupLabel = _T("MC"); } else if (opKind == TOpeningData::OP_TWODOOR) { csSectionLabel = _T("TwoDoor"); csFixupLabel = _T("ZM"); } else if (opKind == TOpeningData::OP_GROUP) { csSectionLabel = _T("GroupOpening"); if (IsDoor()) csFixupLabel = _T("ZM"); else csFixupLabel = _T("ZC"); } bool bFlag = false; // 标记是否已经正确从OpeningLabel.ini文件中得到标注前缀 TOpeningLabelData data; CString csNewName; if (!csSectionLabel.IsEmpty()) // 类别不为空时 { // 获得门窗类型 CString csSubKind = GetSubKind(); bFlag = data.GetOpeningLabel(csSectionLabel, csSubKind, csNewName); } if (!bFlag) // 如果没有得到正确的数据,输出固定的标注前缀 csNewName = csFixupLabel; // 获得是否需要添加连字符 CString csHypen = _T(""); if (data.HasHypen()) csHypen = _T("-"); bool bRound = data.IsRound(); // 是否进行四舍五入 // 获得标注方式 TOpeningLabelData::ESerialRule nRule = data.GetNumRule(); if (nRule == TOpeningLabelData::kSize) // 按尺寸标注 { 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);//add by whl else if (nWidth1>9&&nHeight1<10) csNewName.Format(_T("%s%s%d0%d"),csNewName, csHypen, nWidth1, nHeight1);//add by whl else // if(nWidth<10&&nHeight<10) csNewName.Format(_T("%s%s0%d0%d"),csNewName, csHypen, nWidth1, nHeight1);//add by whl bAddNum = false; } else // 按数序排列 { csNewName.Format(_T("%s%s"), csNewName, csHypen); bAddNum = true; // 由对话框处进行+1工作 } return csNewName; } BOOL TDbOpening::IsValid() const { BOOL bRet = TDbEntity::IsValid(); if (!bRet) return bRet; bRet = (m_nWidth>_DIST_SNAP && m_nThickness>_DIST_SNAP); return bRet; } TEntityBase::DrawType TDbOpening::GetDrawType() const { if (!Has3D()) return k2DOnly; return k2Dand3D; } // 提供对格式刷的支持 void TDbOpening::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag) { assertWriteEnabled(); TDbEntity::CopyPropertiesFrom(pSrcEntity, gMatchFlag); TDbOpening *pSrc=TDbOpening::cast(pSrcEntity); if(pSrc) { m_nWidth=pSrc->m_nWidth; m_nThickness=pSrc->m_nThickness; m_nHeight=pSrc->m_nHeight; if(pSrc->m_nIdOfWall == m_nIdOfWall) { m_nRotation=pSrc->m_nRotation; m_nQuadrant=pSrc->m_nQuadrant; //象限0,1,2,3代表第1~4象限, m_nRotation为象限的X正方向 } m_opKind=pSrc->m_opKind; // 门窗类型 // sg add 110908,根据8.5的需求,格式刷要支持子类型 SetSubKind(pSrc->GetSubKind()); m_nBulge=pSrc->m_nBulge; //对于弧形窗不为0 m_sLabel=pSrc->m_sLabel; //标号 if(database()==NULL|| pSrcEntity->database()==NULL|| database()==pSrcEntity->database())//add by whl on 060317 { m_nIdStyle2d=pSrc->m_nIdStyle2d; m_nIdStyle3d=pSrc->m_nIdStyle3d; //块表中的ID } m_nOpStyle=pSrc->m_nOpStyle; //是否包含门窗套等标记 m_nSlotExt=pSrc->m_nSlotExt; m_nSlotWidth=pSrc->m_nSlotWidth; //伸出墙的距离,窗套宽度 m_nDoorWidth=pSrc->m_nDoorWidth; m_nWinHeight=pSrc->m_nWinHeight; //门联窗门宽(或子母大门宽)和窗高 m_ptLocation.z=pSrc->m_ptLocation.z;//add by whl on 060411,窗台高 if(pSrc->m_pBayWin) { if(!m_pBayWin) m_pBayWin=new XBayWindow; memcpy(m_pBayWin, pSrc->m_pBayWin, sizeof(XBayWindow)); } else { if(m_pBayWin) { delete m_pBayWin; m_pBayWin=NULL; } } // TArch6 data if(database()==NULL|| pSrcEntity->database()==NULL|| database()==pSrcEntity->database())//add by whl on 060317 { m_idTextStyle=pSrc->m_idTextStyle; m_idLayerText=pSrc->m_idLayerText; //文字样式和图层 m_idLayerGlass3d=pSrc->m_idLayerGlass3d; m_idLayerFrame3d=pSrc->m_idLayerFrame3d; m_idLayerSlab3d=pSrc->m_idLayerSlab3d; //玻璃、窗框和窗台板的图层 } m_nTextHeight=pSrc->m_nTextHeight; //文字转角,文字高度 m_uFrame=pSrc->m_uFrame; m_vFrame=pSrc->m_vFrame; //窗框(竖直)高度和窗框(水平)厚度 m_nSlabThickness=pSrc->m_nSlabThickness; //窗台板厚 m_lstFrameLines.Reset(); //待映射的窗框线,不包括外框 for(int n=0; nm_lstFrameLines.Length(); n++) { m_lstFrameLines.Append(new XCurveSegment(*pSrc->m_lstFrameLines[n])); } m_colorText=pSrc->m_colorText; m_nOpStyleEx=pSrc->m_nOpStyleEx; m_nProWinSlabWidth=pSrc->m_nProWinSlabWidth; } } /////////////////////////////////////////////////////////////////////// // 访问属性的方法 Acad::ErrorStatus TDbOpening::subGetClassID(CLSID* pClsid) const { return Acad::eOk; } // 从DWG读入数据: Acad::ErrorStatus TDbOpening::dwgInFields (AcDbDwgFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = TDbEntity::dwgInFields(pFiler); if(es != Acad::eOk) return es; Adesk::UInt8 nVer; pFiler->readItem(&nVer); if(nVer>g_nVersion) {// Version is too new return Acad::eMakeMeProxy; } pFiler->readItem(&(AcGePoint3d &)m_ptLocation); //含Z坐标,作为窗台高度 pFiler->readItem(&m_nWidth); pFiler->readItem(&m_nThickness); pFiler->readItem(&m_nHeight); // nWidth有正负, nHeight>0 pFiler->readItem(&m_nRotation); // 0~2*PI pFiler->readItem(&m_nQuadrant); Adesk::UInt8 nKind; pFiler->readItem(&nKind); m_opKind = (OpeningKind)nKind; pFiler->readItem(&m_nBulge); //对于弧形窗不为0 TCHAR *pBuffer=NULL; pFiler->readString(&pBuffer); assert(pBuffer); m_sLabel=pBuffer; acdbFree(pBuffer); pFiler->readItem(&m_nIdStyle2d); pFiler->readItem(&m_nIdStyle3d); pFiler->readItem(&(AcGePoint3d &)m_ptLabel); pFiler->readItem(&m_nIdOfWall); if(nVer>1) // TArch6 pFiler->readItem(&m_nOpStyle); else { // Upgrade Adesk::UInt8 oldStyle=0; pFiler->readItem(&oldStyle); m_nOpStyle=oldStyle; if(HasSlot()) SetSlot3d(TRUE); } if(HasSlot()) { pFiler->readItem(&m_nSlotExt); pFiler->readItem(&m_nSlotWidth); } if (m_opKind==OP_PROWIN) { if(!m_pBayWin) m_pBayWin = new XBayWindow; // sg modify 120518,在凸窗中增加了数据,间接需要版本号来增加数据 // VERIFY(m_pBayWin->dwgInFields(pFiler)==Acad::eOk); VERIFY(m_pBayWin->dwgInFields(pFiler, nVer)==Acad::eOk); } else if(m_opKind==OP_DOORWIN || m_opKind==OP_TWODOOR) { pFiler->readItem(&m_nDoorWidth); if(m_opKind==OP_DOORWIN) pFiler->readItem(&m_nWinHeight); } m_lstFrameLines.Reset(); m_idLayerGlass3d=m_idLayerFrame3d=m_idLayerSlab3d=AcDbObjectId::kNull; if(nVer>1) { // TArch6 pFiler->readItem(&m_idTextStyle); pFiler->readItem(&m_idLayerText); pFiler->readItem(&m_idLayerGlass3d); pFiler->readItem(&m_idLayerFrame3d); pFiler->readItem(&m_idLayerSlab3d); pFiler->readItem(&m_nTextHeight); pFiler->readItem(&m_nSlabThickness); pFiler->readItem(&m_uFrame); pFiler->readItem(&m_vFrame); Adesk::UInt16 nCount=0; pFiler->readItem(&nCount); for(Adesk::UInt16 n=0; nreadItem(&(AcGePoint2d &)pt1); pFiler->readItem(&(AcGePoint2d &)pt2); pFiler->readItem(&val); m_lstFrameLines.Append(new XCurveSegment(pt1, pt2, val, LS_FINITE)); } } else { if(database()==acdbCurDwg()) { m_idTextStyle = InitTextStyle(TS_WINDOW); m_idLayerText = InitLayer(LAY_OPENING_DIM, FALSE); m_idLayerGlass3d = InitLayer(LAY_3DGLASS, FALSE); m_idLayerSlab3d = m_idLayerFrame3d = InitLayer(LAY_3DFRAME, FALSE); } else { m_idTextStyle = GetValidTextStyle(database(), _T("_TCH_WINDOW")); m_idLayerText = GetLayerIdFromString(LAY_OPENING_DIM, database()); m_idLayerGlass3d = GetLayerIdFromString(LAY_3DGLASS, database()); m_idLayerSlab3d = m_idLayerFrame3d = GetLayerIdFromString(LAY_3DFRAME, database()); } } if(nVer>2)//TArch7 { pFiler->readItem(&m_nOpStyleEx); pFiler->readItem(&m_colorText); pFiler->readItem(&m_iEnFlag); ReadString(pFiler,m_sCons); pFiler->readItem(&m_dbAbsorption); pFiler->readItem(&m_dbShadeCo); pFiler->readItem(&m_dbOutShadeCoSum); pFiler->readItem(&m_dbOutShadeCoWin); } if(nVer>3)//TArch8 { pFiler->readItem(&m_nProWinSlabWidth); } return pFiler->filerStatus(); } // 写出数据到dwg: Acad::ErrorStatus TDbOpening::dwgOutFields(AcDbDwgFiler* pFiler) const { assertReadEnabled(); Acad::ErrorStatus es = TDbEntity::dwgOutFields(pFiler); if(es != Acad::eOk) return es; if(g_nSaveTArchVer==5) pFiler->writeItem((Adesk::UInt8)1); else if(g_nSaveTArchVer==6) pFiler->writeItem((Adesk::UInt8)2); else if(g_nSaveTArchVer==7) pFiler->writeItem((Adesk::UInt8)3); else if(g_nSaveTArchVer==8) // sg modify 1200703,9.0升级版本号 pFiler->writeItem((Adesk::UInt8)4); else pFiler->writeItem(g_nVersion); pFiler->writeItem((AcGePoint3d &)m_ptLocation); //含Z坐标,作为窗台高度 pFiler->writeItem(m_nWidth); pFiler->writeItem(m_nThickness); pFiler->writeItem(m_nHeight); // nWidth有正负, nHeight>0 pFiler->writeItem(m_nRotation); // 0~2*PI pFiler->writeItem(m_nQuadrant); Adesk::UInt8 nKind=m_opKind; if(g_nSaveTArchVer<7) { if(IsDoorAsWin()) nKind=OP_WINDOW; } pFiler->writeItem(nKind); pFiler->writeItem(m_nBulge); //对于弧形窗不为0 pFiler->writeString(m_sLabel); pFiler->writeItem(m_nIdStyle2d); pFiler->writeItem(m_nIdStyle3d); pFiler->writeItem((AcGePoint3d &)m_ptLabel); pFiler->writeItem(m_nIdOfWall); if(g_nSaveTArchVer==5) pFiler->writeItem((Adesk::UInt8)m_nOpStyle); else pFiler->writeItem(m_nOpStyle); if(HasSlot()) { pFiler->writeItem(m_nSlotExt); pFiler->writeItem(m_nSlotWidth); } if(m_opKind==OP_PROWIN) { ASSERT(m_pBayWin); VERIFY(m_pBayWin->dwgOutFields(pFiler)==Acad::eOk); } else if(m_opKind==OP_DOORWIN || m_opKind==OP_TWODOOR) { pFiler->writeItem(m_nDoorWidth); if(m_opKind==OP_DOORWIN) pFiler->writeItem(m_nWinHeight); } // TArch6 if(g_nSaveTArchVer>5) { pFiler->writeItem(m_idTextStyle); pFiler->writeItem(m_idLayerText); pFiler->writeItem(m_idLayerGlass3d); pFiler->writeItem(m_idLayerFrame3d); pFiler->writeItem(m_idLayerSlab3d); pFiler->writeItem(m_nTextHeight); pFiler->writeItem(m_nSlabThickness); pFiler->writeItem(m_uFrame); pFiler->writeItem(m_vFrame); Adesk::UInt16 nCount=m_lstFrameLines.Length(); pFiler->writeItem(nCount); for(Adesk::UInt16 n=0; nwriteItem((const AcGePoint2d &)rSeg.StartPoint()); pFiler->writeItem((const AcGePoint2d &)rSeg.EndPoint()); pFiler->writeItem(rSeg.GetBulge()); } } //TArch7 if(g_nSaveTArchVer>6) { pFiler->writeItem(m_nOpStyleEx); pFiler->writeItem(m_colorText); pFiler->writeItem(m_iEnFlag); pFiler->writeString(m_sCons); pFiler->writeItem(m_dbAbsorption); pFiler->writeItem(m_dbShadeCo); pFiler->writeItem(m_dbOutShadeCoSum); pFiler->writeItem(m_dbOutShadeCoWin); } //TArch8 if(g_nSaveTArchVer>7) { pFiler->writeItem(m_nProWinSlabWidth); } return es; } Acad::ErrorStatus TDbOpening::dxfInFields (AcDbDxfFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = TDbEntity::dxfInFields(pFiler); if(es!=Acad::eOk) return es; if (!pFiler->atSubclassData(_T("TDbOpening"))) { return Acad::eBadDxfSequence; } int fieldsFlags=0; resbuf rb; XString s1, s2, s3; Adesk::Int32 bitFlags=0; int n1, n2, n3, n4; double r1, r2, r3, r4, r5, r6; double a1, a2; XPoint pt1, pt2; AcDbObjectId idWall; while ((es == Acad::eOk) && ((es = pFiler->readResBuf(&rb)) == Acad::eOk)) { switch (rb.restype) { case 1: s1=rb.resval.rstring; fieldsFlags |= 0x01; free(rb.resval.rstring); break; case 2: s2=rb.resval.rstring; fieldsFlags |= 0x02; free(rb.resval.rstring); break; case 302: s3=rb.resval.rstring; fieldsFlags |= 0x04; free(rb.resval.rstring); break; case AcDb::kDxfXCoord: pt1=rb.resval.rpoint; fieldsFlags |= 0x08; break; case AcDb::kDxfXCoord+1: pt2=rb.resval.rpoint; fieldsFlags |= 0x10; break; case AcDb::kDxfReal: r1=rb.resval.rreal; fieldsFlags |= 0x20; break; case AcDb::kDxfReal+1: r2=rb.resval.rreal; fieldsFlags |= 0x40; break; case AcDb::kDxfReal+3: r3=rb.resval.rreal; fieldsFlags |= 0x80; break; case AcDb::kDxfReal+4: r4=rb.resval.rreal; fieldsFlags |= 0x100; break; case AcDb::kDxfReal+5: r5=rb.resval.rreal; fieldsFlags |=0x200; break; case AcDb::kDxfReal+6: r6=rb.resval.rreal; fieldsFlags |= 0x400; break; case AcDb::kDxfAngle: a1=rb.resval.rreal; fieldsFlags |= 0x800; break; case AcDb::kDxfAngle+1: a2=rb.resval.rreal; fieldsFlags |= 0x1000; break; case AcDb::kDxfInt16: n1=rb.resval.rint; fieldsFlags |= 0x2000; break; case AcDb::kDxfInt16+1: n2=rb.resval.rint; fieldsFlags |= 0x4000; break; case AcDb::kDxfInt16+2: n3=rb.resval.rint; fieldsFlags |= 0x8000; break; case AcDb::kDxfInt16+3: n4=rb.resval.rint; fieldsFlags |= 0x10000; break; case AcDb::kDxfInt32: bitFlags=rb.resval.rint; break; case AcDb::kDxfSoftPointerId: acdbGetObjectId(idWall, rb.resval.rlname); fieldsFlags |= 0x20000; break; case 147: m_nSlabThickness = rb.resval.rreal; break; case 148: m_uFrame = rb.resval.rreal; break; case 149: m_vFrame = rb.resval.rreal; break; case 7: { XString sName; sName=rb.resval.rstring; free(rb.resval.rstring); m_idTextStyle=TchExport::GetTextStyleId(sName, database()); } break; case 140: m_nTextHeight=rb.resval.rreal; break; case 410: m_idLayerText=LayerString2Id(rb.resval.rstring, database()); free(rb.resval.rstring); break; case 411: m_idLayerGlass3d=LayerString2Id(rb.resval.rstring, database()); free(rb.resval.rstring); break; case 412: m_idLayerFrame3d=LayerString2Id(rb.resval.rstring, database()); free(rb.resval.rstring); break; case 413: m_idLayerSlab3d=LayerString2Id(rb.resval.rstring, database()); free(rb.resval.rstring); break; default: // An unrecognized group. Push it back so that // the subclass can read it again. pFiler->pushBackItem(); es = Acad::eEndOfFile; break; } } // At this point the es variable must contain eEndOfFile // - either from readResBuf() or from pushback. If not, // it indicates that an error happened and we should // return immediately. // if (es != Acad::eEndOfFile) return Acad::eInvalidResBuf; if(!m_idTextStyle) { XString style; if(database()) m_idTextStyle=database()->textstyle(); else { xg_getvar(_T("TEXTSTYLE"), style); m_idTextStyle = TchExport::GetTextStyleId(style, database()); } } if (!(fieldsFlags&0x08)) { pFiler->setError(Acad::eMissingDxfField, _T("\nMissing DXF group code: 10")); return Acad::eMissingDxfField; } if (!(fieldsFlags&0x10)) { pFiler->setError(Acad::eMissingDxfField, _T("\nMissing DXF group code: 11")); return Acad::eMissingDxfField; } if (!(fieldsFlags&0x20)) { pFiler->setError(Acad::eMissingDxfField, _T("\nMissing DXF group code: 40")); return Acad::eMissingDxfField; } if (!(fieldsFlags&0x40)) { pFiler->setError(Acad::eMissingDxfField, _T("\nMissing DXF group code: 41")); return Acad::eMissingDxfField; } if(!!s1) m_nIdStyle2d=GetBlockIdFromString(s1); if(!!s2) m_nIdStyle3d=GetBlockIdFromString(s2); if(fieldsFlags&0x04) m_sLabel=s3; m_ptLocation=pt1; m_ptLabel=pt2; m_nWidth=r1; m_nHeight=r2; if(fieldsFlags&0x80) m_nSlotExt=r3; if(fieldsFlags&0x100) m_nSlotWidth=r4; if(fieldsFlags&0x200) m_nDoorWidth=r5; if(fieldsFlags&0x400) m_nWinHeight=r6; if(fieldsFlags&0x800) m_nRotation=a1; if(fieldsFlags&0x1000) m_nBulge=a2; if(fieldsFlags&0x2000) m_nQuadrant=n1; if(fieldsFlags&0x4000) m_opKind=(OpeningKind)n2; if(m_opKind==OP_PROWIN) { if(!m_pBayWin) m_pBayWin=new XBayWindow; if(fieldsFlags&0x200) m_pBayWin->m_nProtrude=r5; if(fieldsFlags&0x400) m_pBayWin->m_nTrapezia=r6; } if(fieldsFlags&0x8000) m_nOpStyle=n3; if(fieldsFlags&0x10000) { if(m_pBayWin) m_pBayWin->m_nStyle=(XBayWindow::XBayWinStyle)n4; } if(fieldsFlags&0x20000) { m_nIdOfWall=idWall; } //TArch7 m_nOpStyleEx=bitFlags; return pFiler->filerStatus(); } Acad::ErrorStatus TDbOpening::dxfOutFields(AcDbDxfFiler* pFiler) const { assertReadEnabled(); Acad::ErrorStatus es; es = TDbEntity::dxfOutFields(pFiler); assert(es == Acad::eOk); es = pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbOpening")); assert(es == Acad::eOk); /* es = pFiler->writeItem(AcDb::kDxfInt8,g_nVersion); assert(es == Acad::eOk); */ XString sName2d, sName3d; if(!m_nIdStyle2d) ; else sName2d=GetSymbolName(m_nIdStyle2d); if(!m_nIdStyle3d) ; else sName3d=GetSymbolName(m_nIdStyle3d); pFiler->writeString(1, sName2d); pFiler->writeString(2, sName3d); pFiler->writeString(302, m_sLabel); pFiler->writePoint3d(10, m_ptLocation); pFiler->writePoint2d(11, m_ptLabel); pFiler->writeDouble(AcDb::kDxfReal, m_nWidth); pFiler->writeDouble(AcDb::kDxfReal+1, m_nHeight); pFiler->writeDouble(AcDb::kDxfAngle, m_nRotation); pFiler->writeDouble(AcDb::kDxfAngle+1, m_nBulge); pFiler->writeDouble(AcDb::kDxfReal+3, m_nSlotExt); pFiler->writeDouble(AcDb::kDxfReal+4, m_nSlotWidth); pFiler->writeDouble(AcDb::kDxfReal+5, m_pBayWin? m_pBayWin->m_nProtrude : m_nDoorWidth); pFiler->writeDouble(AcDb::kDxfReal+6, m_pBayWin? m_pBayWin->m_nTrapezia : m_nWinHeight); pFiler->writeInt16(AcDb::kDxfInt16, m_nQuadrant); pFiler->writeInt16(AcDb::kDxfInt16+1, m_opKind); pFiler->writeInt16(AcDb::kDxfInt16+2, m_nOpStyle); if(m_pBayWin) pFiler->writeInt16(AcDb::kDxfInt16+3, m_pBayWin->m_nStyle); es = pFiler->writeItem(AcDb::kDxfSoftPointerId,m_nIdOfWall); pFiler->writeDouble(147, m_nSlabThickness); pFiler->writeDouble(148, m_uFrame); pFiler->writeDouble(149, m_vFrame); pFiler->writeString(7, (const TCHAR *)GetSymbolName(m_idTextStyle)); pFiler->writeDouble(140, m_nTextHeight); pFiler->writeString(410, (const TCHAR *)LayerId2String(m_idLayerText)); pFiler->writeString(411, (const TCHAR *)LayerId2String(m_idLayerGlass3d)); pFiler->writeString(412, (const TCHAR *)LayerId2String(m_idLayerFrame3d)); pFiler->writeString(413, (const TCHAR *)LayerId2String(m_idLayerSlab3d)); //TArch7 pFiler->writeItem(AcDb::kDxfInt32,m_nOpStyleEx); return es; } // 克隆门窗的时候 Acad::ErrorStatus TDbOpening::subDeepClone(AcDbObject* pOwner, AcDbObject*& pClonedObject, AcDbIdMapping& idMap, Adesk::Boolean isPrimary) const { Acad::ErrorStatus es=TDbEntity::subDeepClone(pOwner, pClonedObject, idMap, isPrimary); return es; // Modify by ZJQ on 2001/11/29 if(es!=Acad::eOk) return es; if(!m_nIdOfWall) return es; // STEP 8: // if the wall is not beening cloned then modify pcloned if (idMap.deepCloneContext()==AcDb::kDcCopy) { AcDbIdPair idPairWall(m_nIdOfWall, AcDbObjectId::kNull, false, isPrimary? true :false); if(!idMap.compute(idPairWall)) { TDbOpening *pClonedOpening = TDbOpening::cast(pClonedObject); assert(pClonedOpening); pClonedOpening->m_nIdOfWall=AcDbObjectId(); } } // Leave pClonedObject open for the caller // return Acad::eOk; } Acad::ErrorStatus TDbOpening::subGetOsnapPoints( AcDb::OsnapMode osnapMode, INT_PTR gsSelectionMark, const AcGePoint3d& ptPick, const AcGePoint3d& lastPoint, const AcGeMatrix3d& viewXform, AcGePoint3dArray& snapPoints, AcDbIntArray& geomIds) const { assertReadEnabled(); if (osnapMode == AcDb::kOsModeIns) { //插入点捕捉 XPoint ptIns=m_ptLocation; if(!IsExplode3D()) ptIns.z=0; snapPoints.append(ptIns); return Acad::eOk; } return TDbEntity::subGetOsnapPoints(osnapMode, gsSelectionMark, ptPick, lastPoint, viewXform, snapPoints, geomIds); } // ----------------------------------------------------------------------- // Overriden functions for edit // 取夹点 // 依次为插入点, 左右侧点, 开启方向控制点, // 待加标号控制点 Acad::ErrorStatus TDbOpening::subGetGripPoints(AcGePoint3dArray& gripPoints, AcDbIntArray& osnapModes, AcDbIntArray& geomIds) const { //if(TArchCmdReactor::g_sCurCommand==_T("GRIP_STRETCH")) { // if(!!objectId()) // g_idCurStretchOpening=objectId(); //} gripPoints.append(m_ptLocation); // 左右侧点 XPoint ptSideStart, ptSideEnd; GetSidePoints(ptSideStart, ptSideEnd); gripPoints.append(ptSideStart); gripPoints.append(ptSideEnd); XPoint ptQuadrant; ads_polar(m_ptLocation, m_nRotation+m_nQuadrant*PI/2+PI/4, m_nWidth/2.0, ptQuadrant); gripPoints.append(ptQuadrant); if(!(!m_sLabel)) { gripPoints.append(m_ptLabel); } return Acad::eOk; } #if ADS>15 void TDbOpening::CreateGrip() { TDbEntity::CreateGrip(); XCurveSegment curve; if(GetCenterCurve(curve)&&curve.Is(CURVE_LINE)) { GetGrip(0)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimResultantLength)); GetGrip(0)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimDeltaLength,false)); GetGrip(1)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimResultantLength)); GetGrip(1)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimDeltaLength)); GetGrip(1)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimDeltaLength,false)); GetGrip(2)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimResultantLength)); GetGrip(2)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimDeltaLength)); GetGrip(2)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimDeltaLength,false)); } } Acad::ErrorStatus TDbOpening::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; TDbOpening*pEnt=TDbOpening::cast(pEnt0); if(pEnt==NULL) pEnt=this; XPoint vt(wall.EndPoint()-wall.StartPoint()); switch(iGrip) { case 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://位置偏移 { TDbGripDistDim*pDistDim=(TDbGripDistDim*)pDim; XPoint pt; wall.ProjectToMe(pEnt->GetLocation(),pt); pDistDim->SetData(pt.AsAcGePoint3d(),pDim->GripPoint(),800); } break; default: return Acad::eNotImplementedYet; } break; case 1://起点 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; default: return Acad::eNotImplementedYet; } break; case 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; } break; default: return Acad::eNotImplementedYet; } return Acad::eOk; } Acad::ErrorStatus TDbOpening::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(); switch(iGrip) { case 0://位置夹点 switch(iDim) { case 0://宽度 if(newValue>1E-6) SetWidth(newValue); break; case 1://整体偏移 { if(vt.AsAcGeVector3d().dotProduct(offset)>0) vt*=newValue; else vt*=-newValue; m_ptLocation+=vt; m_ptLabel+=vt; } break; } break; case 1://起点 switch(iDim) { case 0://单侧改宽 if(newValue>1E-6) { vt*=((m_nWidth-newValue)/2); m_ptLocation+=vt; m_ptLabel+=vt; SetWidth(newValue); } break; case 1://前垛距 { XCurveSegment seg; XPoint pt; GetNeighbourPoint(pt,true); wall.ProjectToMe(pt,pt); double oldValue=pt.Distance2d(GetGripPoint(iGrip)); // sg modify 110120,根据8.5需求,夹点功能改变,默认为“单侧改宽” // if(GetCtrlToggle())//单侧改宽 if(!GetCtrlToggle())//单侧改宽 { newValue=m_nWidth-newValue+oldValue; if(newValue>1E-6) { vt*=((m_nWidth-newValue)/2); m_ptLocation+=vt; m_ptLabel+=vt; SetWidth(newValue); } } else//整体偏移 { vt*=(newValue-oldValue); m_ptLocation+=vt; m_ptLabel+=vt; } } break; case 2://总体偏移或起点偏移 // sg modify 110120,根据8.5需求,夹点功能改变,默认为“单侧改宽” //if(GetCtrlToggle())//单侧改宽 if(!GetCtrlToggle())//单侧改宽 { if(vt.AsAcGeVector3d().dotProduct(offset)>0) newValue=m_nWidth-newValue; else newValue=m_nWidth+newValue; if(newValue>1E-6) { vt*=((m_nWidth-newValue)/2); m_ptLocation+=vt; m_ptLabel+=vt; SetWidth(newValue); } } else//整体偏移 { if(vt.AsAcGeVector3d().dotProduct(offset)>0) vt*=newValue; else vt*=-newValue; m_ptLocation+=vt; m_ptLabel+=vt; } break; } break; case 2://终点 switch(iDim) { case 0://单侧改宽 { vt*=((newValue-m_nWidth)/2); m_ptLocation+=vt; m_ptLabel+=vt; SetWidth(newValue); } break; case 1://后垛距 { XCurveSegment seg; XPoint pt; GetNeighbourPoint(pt,false); wall.ProjectToMe(pt,pt); double oldValue=pt.Distance2d(GetGripPoint(iGrip)); // sg modify 110120,根据8.5需求,夹点功能改变,默认为“单侧改宽” //if(GetCtrlToggle())//单侧改宽 if(!GetCtrlToggle())//单侧改宽 { newValue=m_nWidth-newValue+oldValue; if(newValue>1E-6) { vt*=((newValue-m_nWidth)/2); m_ptLocation+=vt; m_ptLabel+=vt; SetWidth(newValue); } } else//整体偏移 { vt*=(oldValue-newValue); m_ptLocation+=vt; m_ptLabel+=vt; } } break; case 2://总体偏移或终点偏移 { // sg modify 110120,根据8.5需求,夹点功能改变,默认为“单侧改宽” //if(GetCtrlToggle())//单侧改宽 if(!GetCtrlToggle())//单侧改宽 { if(vt.AsAcGeVector3d().dotProduct(offset)>0) newValue=m_nWidth+newValue; else newValue=m_nWidth-newValue; if(newValue>1E-6) { vt*=((newValue-m_nWidth)/2); m_ptLocation+=vt; m_ptLabel+=vt; SetWidth(newValue); } } else//整体偏移 { if(vt.AsAcGeVector3d().dotProduct(offset)>0) vt*=newValue; else vt*=-newValue; m_ptLocation+=vt; m_ptLabel+=vt; } } break; } break; } return Acad::eOk; } #endif // Stretch的夹点只有插入点和标号位置 Acad::ErrorStatus TDbOpening::subGetStretchPoints(AcGePoint3dArray & stretchPoints) const { stretchPoints.append(m_ptLocation); if (!!m_sLabel) { stretchPoints.append(m_ptLabel); } return Acad::eOk; } // Active when being rotated, scaled, moved, etc. // 在全局旋转之后,仍然要保持旋转角度同墙体一致 Acad::ErrorStatus TDbOpening::subTransformBy(const AcGeMatrix3d& xform) { assertWriteEnabled(); TDbEntity::subTransformBy(xform); //修改原因 : 增加记录 boundary,hatch 命令涉及到的 动态变换矩阵 m_mat3d // 当AcDbBlockRef 中引用到门窗时,对于boundary,hatch 这样的边界分析命令, // 先调用 transformby,然后调用 ExplodeOrDraw2d时,对关联的墙分析有误,此时 // 墙还没有transformby,导致门窗和墙关系不同步错误,boundary,hatch 分析乱线 // 该矩阵不序列化 //修改人 : lfy 2009-11-08 m_mat3d.setToIdentity(); struct resbuf rb; acedGetVar(_T("CMDNAMES"),&rb); CString sCmd = rb.resval.rstring; acutDelString(rb.resval.rstring); if (sCmd.CompareNoCase(_T("BHATCH") ) == 0 || sCmd.CompareNoCase(_T("_BHATCH") ) == 0 || sCmd.CompareNoCase(_T("BOUNDARY")) == 0|| sCmd.CompareNoCase(_T("_BOUNDARY")) == 0|| //add by xlc on 110304 解决弧墙上的门窗移动复制时飞线问题 sCmd.CompareNoCase(_T("MOVE")) == 0|| sCmd.CompareNoCase(_T("COPY")) == 0|| sCmd.CompareNoCase(_T("_MOVE")) == 0|| sCmd.CompareNoCase(_T("_COPY")) == 0 ) { m_mat3d = xform; } XPoint ptQuadrant; ads_polar(m_ptLocation, m_nRotation+m_nQuadrant*PI/2+PI/4, m_nWidth/2.0, ptQuadrant); AcGePoint3d &pt=m_ptLocation; pt.transformBy(xform); ((AcGePoint3d &)m_ptLabel).transformBy(xform); /* if(!!m_nIdOfWall) { AcDbObjectIdArray idArray; if(acdbGetCurrentSelectionSet(idArray)!=Acad::eOk) return Acad::eInvalidInput; if(idArray.contains(m_nIdOfWall)) ; //墙也参与变换 else { //墙没有参与变换 XDbObject obj(m_nIdOfWall, AcDb::kForRead); if(!(!obj)) { TDbWall *pWall = TDbWall::cast(obj.m_pObject); m_nRotation = pWall->Direction(m_ptLocation); } } }*/ XVector3D vtRot(cos(m_nRotation), sin(m_nRotation)); ((AcGeVector3d &)vtRot).transformBy(xform); m_nRotation=ads_angle(XPoint(), vtRot); // 对开向控制点进行变换 { ((AcGePoint3d &)ptQuadrant).transformBy(xform); ads_real nAng=CT_std_angle(ads_angle(m_ptLocation, ptQuadrant)-m_nRotation); if(nAng>=0.0 && nAng=PI/2.0 && nAng=PI && nAng<1.5*PI) m_nQuadrant=2; else m_nQuadrant=3; } ads_matrix mat; AsAdsMatrix(xform,mat); if(IsMirrorMatrix(mat)) { if(HasLeftSlab()&&!HasRightSlab()) SetSideSlab(3); else if(HasRightSlab()&&!HasLeftSlab()) SetSideSlab(2); } return Acad::eOk; } // 功能: 夹点操作 // 方法: // 1. 移动插入点: 固定门窗在墙体的轨迹上移动 // 2. 拖曳镜像点: 用来改变开启方向 Acad::ErrorStatus TDbOpening::subMoveGripPointsAt( const AcDbIntArray& indices, const AcGeVector3d& offset) { assertWriteEnabled(); XPoint vtOffset=*(XPoint *)&offset; vtOffset.z = 0; double nSill=m_ptLocation.z; for (int i = 0; i < indices.length(); i++) { int idx = indices[i]; switch(idx) { case 0: case 1: case 2: { // 移动边界,单侧改宽度 // sg modify 110120,根据8.5需求,夹点功能改变,默认为“单侧改宽” // if(idx==0 || !GetCtrlToggle()) if(idx==0 || GetCtrlToggle()) // 移动位置 { XVector3D vt0=vtOffset; if(g_bModelNumber && IsLinear()) {//模数开关 ASSERT(g_nWinStep>1.0E-3); double nLen=vt0.Length(); vt0 /= nLen; nLen = AS_INT(nLen/g_nWinStep)*g_nWinStep; vt0 *= nLen; } XDbObject objWall(m_nIdOfWall, AcDb::kForRead); TDbWall *pWall0 = !objWall? NULL : TDbWall::cast(objWall.m_pObject); XPoint ptDest = m_ptLocation + vt0; m_ptLocation += vt0; m_ptLabel += vt0; m_ptLocation.z = nSill; //不改变窗台高度 m_ptLabel.z = 0; } else // 单侧改宽 { XPoint ptSideStart, ptSideEnd; GetSidePoints(ptSideStart, ptSideEnd); XPoint &ptSide = (idx==1? ptSideStart:ptSideEnd); XPoint &ptOtherSide = (idx==1? ptSideEnd : ptSideStart); ptSide += vtOffset; OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall); if(pWall) { // sg modify 110127,获得墙体基线时,考虑保温厚,放置门窗对象拖拽夹点后发生宽度错误 // XCurveSegment segCenter=pWall->OffsetGeomCenter(); XCurveSegment segCenter=pWall->OffsetGeomCenter(LS_INFINITE, TRUE); segCenter.SetElevation(m_ptLocation.z); segCenter.ProjectToMe(XPoint(ptSide), ptSide); } OPENOBJ_END(); if(g_bModelNumber && IsLinear()) {//模数开关 ASSERT(g_nWinStep>1.0E-3); double nAng=ads_angle(ptOtherSide, ptSide); double nSize=ads_distance(ptOtherSide, ptSide); nSize = AS_INT(nSize/g_nWinStep)*g_nWinStep; ads_polar(ptOtherSide, nAng, nSize, ptSide); } SetSidePoints(ptSideStart, ptSideEnd); } } break; case 3: {//Move quadrant point XPoint ptQuadrant; ads_polar(m_ptLocation, m_nRotation+m_nQuadrant*PI/2+PI/4, m_nWidth/2.0, ptQuadrant); ptQuadrant += vtOffset; ptQuadrant.z = nSill; int nOldQuadrant=m_nQuadrant; ads_real nAng=CT_std_angle(ads_angle(m_ptLocation, ptQuadrant)-m_nRotation); if(nAng>=0.0 && nAng=PI/2.0 && nAng=PI && nAng<1.5*PI) m_nQuadrant=2; else m_nQuadrant=3; // 假如由0/1变为2/3,或由2/3变为0/1,着对标号位置进行镜像 if((nOldQuadrant<2 && m_nQuadrant>=2) || (nOldQuadrant>=2 && m_nQuadrant<2)) { XLine ln(m_ptLocation, m_nRotation); ln.SetElevation(m_ptLabel.z); XPoint ptPrj; if(m_ptLabel.Project(&ln, ptPrj)==RTNORM) { ptPrj.Mirror(XPoint(m_ptLabel), m_ptLabel); } //add by xlc on 110215 调整单侧门口线开启侧 if (!( (m_nOpStyleEx & OPS_DOORLINE_MID) //居中 || (m_nOpStyle & (OPS_DOORLINE1+OPS_DOORLINE2)) == 0 //无门口线 || (m_nOpStyle | (OPS_DOORLINE1+OPS_DOORLINE2)) == m_nOpStyle //双侧门口线 ) ) { if (m_nOpStyle & OPS_DOORLINE1) { m_nOpStyle &= ~OPS_DOORLINE1; } else { m_nOpStyle |= OPS_DOORLINE1; } if (m_nOpStyle & OPS_DOORLINE2) { m_nOpStyle &= ~OPS_DOORLINE2; } else { m_nOpStyle |= OPS_DOORLINE2; } } } } break; case 4: // move label m_ptLabel += vtOffset; break; } } return Acad::eOk; } // 取夹点的说明 Acad::ErrorStatus TDbOpening::GetGripText(int i, CString &cs) const { Acad::ErrorStatus es=Acad::eOk; switch(i) { case 0: cs=_T("移动门窗"); break; case 1: case 2: { // sg modify 110120,根据8.5需求,夹点功能改变,默认为“单侧改宽” // cs=GetCtrlToggle()? _T("单侧改宽(Ctrl-移动门窗)") : _T("移动门窗(Ctrl-单侧改宽)"); cs=GetCtrlToggle() ? _T("移动门窗(Ctrl-单侧改宽)") : _T("单侧改宽(Ctrl-移动门窗)"); } break; case 3: cs=_T("改变开启方向"); break; case 4: cs=_T("改变编号位置"); break; default: es=Acad::eInvalidInput; } return es; } Acad::ErrorStatus TDbOpening::DownGradeSave(int nDrawMode, AcDbVoidPtrArray &entSet, BOOL *bErase) { if(g_nSaveTArchVer==5) { Acad::ErrorStatus es=Acad::eOk; if((nDrawMode&DRAW_2D) && GetKind()==TOpeningData::OP_DOOR) { //门口线 XExplodeStream dc(entSet); dc.SetPropertiesFrom(this);//add by whl on 060218 DrawDoorLine(dc); } } return TDbEntity::DownGradeSave(nDrawMode,entSet,bErase); } int TDbOpening::ConvertText(TConvertTextPtr ptr, void *pData) { XString sText; int nRet=ptr(m_sLabel, sText, pData); if(nRet==RTNORM) { assertWriteEnabled(); m_sLabel=sText; } return nRet; } void TDbOpening::GetLabelText(TDbText &text) const { AcDbObjectId idTextStyle=m_idTextStyle; if(!idTextStyle.isValid()) idTextStyle=InitTextStyle(TS_WINDOW,database()); XString sStyleName=GetSymbolName(idTextStyle); text.SetStyleId(idTextStyle); text.setPropertiesFrom(this); text.SetHeight(m_nTextHeight); text.SetAlignment(XExplodeDraw::kMiddleCenter); text.SetLocation(XPoint(m_ptLabel.x, m_ptLabel.y)); double nRotLabel=m_nRotation; if(GetKind()==OP_CORNWIN || GetKind()==OP_ARCWIN) { if(!!m_nIdOfWall) { OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall); if(pWall && pWall->Is(CURVE_ARC)) { XArc ar=pWall->GetArc(); nRotLabel=CT_std_angle(ads_angle(ar.GetCenterPt(), m_ptLabel)-PI/2); } OPENOBJ_END(); } } text.SetRotation(xg_angle(nRotLabel)); text.SetText(m_sLabel); } // 返回发现的位置,同时posStart往前移动(以便继续找下一个使用), TTextPosition TDbOpening::FindSubText(const TCHAR *sSubText, TTextPosition &posStart, TTextRange *pRange) const { assertReadEnabled(); TDbText text; GetLabelText(text); TTextPosition pos=text.FindSubText(sSubText, posStart, pRange); return pos; } // 返回下一次查找的开始位置 TTextPosition TDbOpening::ReplaceSubText(const TTextPosition &posRep, const TCHAR *sRepText, TTextRange *pRange) { assertWriteEnabled(); TDbText text; GetLabelText(text); TTextPosition pos=text.ReplaceSubText(posRep, sRepText, pRange); SetLabel(text.GetText()); return pos; } // 功能: 夹点操作 Acad::ErrorStatus TDbOpening::subMoveStretchPointsAt( const AcDbIntArray& indices, const AcGeVector3d& offset) { assertWriteEnabled(); XPoint vtOffset=*(XPoint *)&offset; vtOffset.z=0; for (int i = 0; i < indices.length(); i++) { int idx = indices[i]; switch(idx) { case 0: // InsertPoint m_ptLocation += vtOffset; break; case 1: m_ptLabel += vtOffset; break; } } return Acad::eOk; } //通知墙体已经被修改过 Acad::ErrorStatus TDbOpening::subClose() { Acad::ErrorStatus es = TDbEntity::subClose(); if(es==Acad::eOk && !(!m_nIdOfWall) && isModified() && database()==acdbCurDwg()) { OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall); if(pWall) { if(!pWall->isModified()) { if(pWall->upgradeOpen()==Acad::eOk) pWall->recordGraphicsModified(); } } OPENOBJ_END(); } return es; } // 解除同墙体之间的引用关系 Acad::ErrorStatus TDbOpening::subErase(Adesk::Boolean bErasing) { extern BOOL SkipSubErase(const TCHAR *szCmd); Acad::ErrorStatus es = TDbEntity::subErase(bErasing); if(es==Acad::eOk && bErasing==Adesk::kTrue && !(!m_nIdOfWall)) { #if (ADS>14) XString &sCmd=GetCurDocData()->m_sCurCommand; #else XString &sCmd=TArchCmdReactor::g_sCurCommand; #endif if(!TchPrivate::SkipSubErase(sCmd)) { XDbObject obj(m_nIdOfWall, AcDb::kForWrite); if(!(!obj)) { TDbWall *pWall = TDbWall::cast(obj.m_pObject); if(pWall) pWall->RemoveReferenceOpening(objectId()); } } } return es; } Acad::ErrorStatus TDbOpening::subOpen(AcDb::OpenMode mode) { Acad::ErrorStatus es=TDbEntity::subOpen(mode); extern BOOL g_bMonitorDbAction; if(es==Acad::eOk && mode==AcDb::kForWrite &&!isNewObject()&& database()==acdbCurDwg() && g_bDwgBegin && TchGeLib::g_bMonitorDbAction) BackupPoints(); return es; } BOOL TDbOpening::DrawDoorOrWin3d(XExplodeDraw &dc, const XLine &lnPos, BOOL bDoor) const { //TPushProperty vProp(this, dc); AcDbObjectId idStyle=bDoor? m_nIdStyle2d : m_nIdStyle3d; XPoint origenalSize; if(!GetOriginal3DSize(idStyle, origenalSize)) return FALSE; double nScaleX, nScaleY, nScaleZ; nScaleX = origenalSize.x>_DIST_SNAP? (lnPos.GetLength()/origenalSize.x) : 1.0; nScaleY = 1.0; //origenalSize.y>_DIST_SNAP? (m_nThickness/origenalSize.y) : 1.0; double nSizeZ=(bDoor? m_nHeight:m_nWinHeight); if(m_opKind==OP_TWODOOR) nSizeZ=m_nHeight; nScaleZ = origenalSize.z>_DIST_SNAP? (nSizeZ/origenalSize.z) : 1.0; if(origenalSize.y>origenalSize.x/2.0) //旋转门 nScaleY=nScaleX; XPoint ptIns; OPENOBJ_BEGIN(idStyle, AcDb::kForRead, AcDbBlockTableRecord, pBlock); if(!pBlock) return FALSE; ptIns = lnPos.MidPoint(); OPENOBJ_END(); dc<_DIST_SNAP); XPoint ptArray[5]; XPoint ptBase=m_ptLocation; ptBase.z=0.0; ads_polar(ptBase, m_nRotation+PI, m_nWidth/2, ptArray[0]); ads_polar(ptArray[0], m_nRotation, nWidth1, ptArray[1]); ads_polar(ptBase, m_nRotation, m_nWidth/2, ptArray[2]); ads_polar(ptArray[0], m_nRotation+PI/2, nWidth1, ptArray[3]); ads_polar(ptArray[2], m_nRotation+PI/2, nWidth2, ptArray[4]); AcDbPolyline pline; pline.setPropertiesFrom(this); pline.addVertexAt(0, ptArray[0]); pline.addVertexAt(1, ptArray[3], -tan(PI/8)); pline.addVertexAt(2, ptArray[1], -tan(PI/8)); pline.addVertexAt(3, ptArray[4]); pline.addVertexAt(4, ptArray[2]); AcGeMatrix3d mat; if(m_nQuadrant==1) { AcGeLine3d ln(ptBase, AcGeVector3d(cos(m_nRotation+PI/2),sin(m_nRotation+PI/2),0)); mat.setToMirroring(ln); VERIFY(pline.transformBy(mat)==Acad::eOk); } else if(m_nQuadrant==2) { mat.setToMirroring(ptBase); VERIFY(pline.transformBy(mat)==Acad::eOk); } else if(m_nQuadrant==3) { AcGeLine3d ln(ptBase, AcGeVector3d(cos(m_nRotation),sin(m_nRotation),0)); mat.setToMirroring(ln); VERIFY(pline.transformBy(mat)==Acad::eOk); } if(bDraw3d) { XPoint pt0, pt1, pt2; pline.getPointAt(0, (AcGePoint3d &)pt0); pline.getPointAt(2, (AcGePoint3d &)pt1); pline.getPointAt(4, (AcGePoint3d &)pt2); XLine ln1(pt0,pt1), ln2(pt1, pt2); ln1.SetElevation(m_ptLocation.z); ln2.SetElevation(m_ptLocation.z); DrawDoorOrWin3d(dc, ln1, FALSE); DrawDoorOrWin3d(dc, ln2, TRUE); } else { dc.DrawEntity(pline); } } // 绘制或分解门联窗 void TDbOpening::ExplodeOrDrawDoorWin(XExplodeDraw &dc, BOOL bDraw3d) const { double nWinWidth=m_nWidth-m_nDoorWidth; ASSERT(nWinWidth>0); double nWallThick=GetWallThickness(TRUE); if(m_nQuadrant==0 || m_nQuadrant==3) { // 画窗 XPoint ptWinSide[2]; ads_polar(m_ptLocation, m_nRotation+PI, m_nWidth/2, ptWinSide[0]); ads_polar(ptWinSide[0], m_nRotation, nWinWidth, ptWinSide[1]); ptWinSide[0].z=ptWinSide[1].z=bDraw3d? m_ptLocation.z+m_nHeight-m_nWinHeight : 0.0; XLine lnMidWin(ptWinSide[0], ptWinSide[1]); if(!bDraw3d || !DrawDoorOrWin3d(dc, lnMidWin, FALSE)) { if(bDraw3d) { dc.DrawLine(lnMidWin.Offset(nWallThick/6), m_nWinHeight); dc.DrawLine(lnMidWin.Offset(-nWallThick/6), m_nWinHeight); } else { dc<ProjectToMe(XPoint(ptStart), ptStart); pWall->ProjectToMe(XPoint(ptEnd), ptEnd); segMid = pWall->GetFinalOffsetCurveFromCenter(OFFSET_LEFT, 0.0); segLeft = pWall->GetFinalOffsetCurveFromCenter(OFFSET_LEFT, 1.0/6.0); segRight = pWall->GetFinalOffsetCurveFromCenter(OFFSET_RIGHT, 1.0/6.0); //modify by xlc on 110311 墙材料不同时墙边线计算有误 //pWall->GetSideCurve(segLeftSide, segRightSide, 0.0, TRUE); pWall->GetStandardCurve(segLeftSide, segRightSide, 0.0, TRUE); XPoint ptLeftStart = segLeft.StartPoint(), ptLeftEnd = segLeft.EndPoint(), ptRightStart = segRight.StartPoint(), ptRightEnd = segRight.EndPoint(), ptMidStart=segMid.StartPoint(), ptMidEnd=segMid.EndPoint(), ptLeftSideStart = segLeftSide.StartPoint(), ptLeftSideEnd = segLeftSide.EndPoint(), ptRightSideStart = segRightSide.StartPoint(), ptRightSideEnd = segRightSide.EndPoint(); BOOL bAcrossStart=FALSE, bAcrossEnd=FALSE; if(ptStart.Distance2d(pWall->StartPoint())<_DIST_SNAP) { if(!!pWall->m_idLeftStart) { OPENOBJ_BEGIN(pWall->m_idLeftStart, AcDb::kForRead, TDbWall, pLeftStart); if(pLeftStart && pLeftStart->HasCornerWinAcrossPoint(ptStart)) { //add by xlc on 120510 解决丁字形墙上带形窗缺口问题 //转角处两个窗户平行时不作为转角窗处理 if (!IsSameDrtAtPt(*pWall, *pLeftStart, ptStart)) { bAcrossStart=TRUE; } } OPENOBJ_END(); } if(!!pWall->m_idRightStart) { OPENOBJ_BEGIN(pWall->m_idRightStart, AcDb::kForRead, TDbWall, pRightStart); if(pRightStart && pRightStart->HasCornerWinAcrossPoint(ptStart)) { //add by xlc on 120510 解决丁字形墙上带形窗缺口问题 //转角处两个窗户平行时不作为转角窗处理 if (!IsSameDrtAtPt(*pWall, *pRightStart, ptStart)) { bAcrossStart=TRUE; } } OPENOBJ_END(); } } if(ptEnd.Distance2d(pWall->EndPoint())<_DIST_SNAP) { if(!!pWall->m_idLeftEnd) { OPENOBJ_BEGIN(pWall->m_idLeftEnd, AcDb::kForRead, TDbWall, pLeftEnd); if(pLeftEnd && pLeftEnd->HasCornerWinAcrossPoint(ptEnd)) { //add by xlc on 120510 解决丁字形墙上带形窗缺口问题 //转角处两个窗户平行时不作为转角窗处理 if (!IsSameDrtAtPt(*pWall, *pLeftEnd, ptEnd)) { bAcrossEnd=TRUE; } } OPENOBJ_END(); } if(!!pWall->m_idRightEnd) { OPENOBJ_BEGIN(pWall->m_idRightEnd, AcDb::kForRead, TDbWall, pRightEnd); if(pRightEnd && pRightEnd->HasCornerWinAcrossPoint(ptEnd)) { //add by xlc on 120510 解决丁字形墙上带形窗缺口问题 //转角处两个窗户平行时不作为转角窗处理 if (!IsSameDrtAtPt(*pWall, *pRightEnd, ptEnd)) { bAcrossEnd=TRUE; } } OPENOBJ_END(); } } if(!bAcrossStart) {//不在起角点 segLeft.ProjectToMe(ptStart, ptLeftStart); segRight.ProjectToMe(ptStart, ptRightStart); segMid.ProjectToMe(ptStart, ptMidStart); segLeftSide.ProjectToMe(ptStart, ptLeftSideStart); segRightSide.ProjectToMe(ptStart, ptRightSideStart); } if(!bAcrossEnd) {//不在终角点 segLeft.ProjectToMe(ptEnd, ptLeftEnd); segRight.ProjectToMe(ptEnd, ptRightEnd); segMid.ProjectToMe(ptEnd, ptMidEnd); segLeftSide.ProjectToMe(ptEnd, ptLeftSideEnd); segRightSide.ProjectToMe(ptEnd, ptRightSideEnd); } segLeft.SetPoints(ptLeftStart, ptLeftEnd); segRight.SetPoints(ptRightStart, ptRightEnd); segMid.SetPoints(ptMidStart, ptMidEnd); segLeftSide.SetPoints(ptLeftSideStart, ptLeftSideEnd); segRightSide.SetPoints(ptRightSideStart, ptRightSideEnd); OPENOBJ_END(); double nElev=0.0; segLeft.SetElevation(nElev); segRight.SetElevation(nElev); segLeftSide.SetElevation(nElev); segRightSide.SetElevation(nElev); segMid.SetElevation(nElev); return TRUE; } // 绘制带窗 BOOL TDbOpening::DrawBanWin(XExplodeDraw &dc, BOOL bDraw3d) const { XCurveSegment segLeftSide, segLeft, segMid, segRight, segRightSide; if(!GetBanWinSegs(segLeftSide, segLeft, segMid, segRight, segRightSide)) return FALSE; double nThick= bDraw3d? m_nHeight:0.0; double nElev=bDraw3d? GetElevation() : 0.0; segLeft.SetElevation(nElev); segRight.SetElevation(nElev); segLeftSide.SetElevation(nElev); segRightSide.SetElevation(nElev); segMid.SetElevation(nElev); if(bDraw3d) { TMasterProperties prop; dc.BackUpProperties(prop); dc.SetColorLayer(colorIndex(), m_idLayerGlass3d); dc.DrawCurve(segMid, nThick); dc.RestoreProperties(prop); // 绘制窗框 dc.SetColorLayer(colorIndex(), m_idLayerFrame3d); XPoly2D polyGlass; segMid.AsPoly2D(polyGlass); DrawFrame3d(dc, polyGlass); dc.RestoreProperties(prop); } else { /* if (GetPScale()>g_nCurtainWall3Scale+1.0E-3) { dc<g_nCurtainWall3Scale+1.0E-3) { dc<GetWidth(4); ads_polar(ptLoc, nExtDir, 10000, ptDir); int nSide = pWall->OnWhichSide(ptDir); // 得到外保温厚度 if (pWall->IsInsulateOnSide(nSide)) { dWallInsut = pWall->GetInsulateThick(nSide); if (DocGetProWinSlabInsu()) { // 外墙和内墙同时使用这一个参数,所以内外只能有一种保温存在 dInsutAdd = GetSlotInsulateThick(); nInsulateType = 1; } } // 如果有内保温需要补豁口 ads_polar(ptLoc, nExtDir, -10000, ptDir); if (pWall->IsInsulateOnSide(pWall->OnWhichSide(ptDir))) { dInsutAdd = GetSlotInsulateThick(); nInsulateType = (nInsulateType==1) ? 2 : 1; } } OPENOBJ_END(); // wlw add 100913 DList polyCurves; // m_pBayWin->GetPolyCurve(ptLoc, nExtDir, m_nWidth, nWallThick, HasLeftSlab(), HasRightSlab(), polyCurves, dWallInsut, dInsutAdd); m_pBayWin->GetPolyCurve(ptLoc, nExtDir, m_nWidth, nWallThick, HasLeftSlab(), HasRightSlab(), polyCurves, dWallInsut, dInsutAdd, nInsulateType==2); for (int idx=0; idx_DIST_SNAP) // 有窗台 { XPoint ptSide1, ptSide2; GetSidePoints(ptSide1, ptSide2); ads_polar(XPoint(ptSide1), nExtDir-PI, nWallThick/2.0, ptSide1); ads_polar(XPoint(ptSide2), nExtDir-PI, nWallThick/2.0, ptSide2); ptSide1.z = ptSide2.z = 0; double dLine = 0.0; m_XDataMap.GetAt(sKEY_OP_PROWIN_LINE, dLine); if (dLine < 0.01) { dc << XLine(ptSide1, ptSide2); } } return TRUE; } void TDbOpening::DrawDoorLine(XExplodeDraw &dc) const { // add by xlc on 110222 无门口线时不计算 if ((m_nOpStyleEx & OPS_DOORLINE_MID) //门口线居中 || (m_nOpStyle&OPS_DOORLINE1) //门口线单侧 || (m_nOpStyle&OPS_DOORLINE2)) //门口线单侧 { } else { return; } TADSGePoint3d ptSide1, ptSide2; GetSidePoints(ptSide1, ptSide2); OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pDbWall); if (pDbWall) { double dWallThick = pDbWall->GetWidth(4); TGGeLine ln1,ln2; TGGeLine lnMid(ptSide1, ptSide2); TGGeCurveSegment cv1,cv2; TGGeCurveSegment segMid = pDbWall->OffsetGeomCenter(LS_FINITE, TRUE); // modify by xlc on 110214 增加门口线偏移距离和居中功能 //cv1 = segMid.Offset(dWallThick / 2.0, LS_FINITE); //cv2 = segMid.Offset(-dWallThick / 2.0, LS_FINITE); //ln1 = lnMid.Offset(dWallThick / 2.0); //ln2 = lnMid.Offset(-dWallThick / 2.0); if (m_nOpStyleEx & OPS_DOORLINE_MID) //门口线居中 { segMid.SetPoints(ptSide1, ptSide2); dc << segMid; return; } double dOffsetDist = GetDoorLineOffsetDist(); cv1 = segMid.Offset(dWallThick / 2.0 - dOffsetDist, LS_FINITE); cv2 = segMid.Offset(-dWallThick / 2.0 + dOffsetDist, LS_FINITE); ln1 = lnMid.Offset(dWallThick / 2.0 - dOffsetDist); ln2 = lnMid.Offset(-dWallThick / 2.0 + dOffsetDist); cv1.SetPoints(ln1.StartPoint(), ln1.EndPoint()); cv2.SetPoints(ln2.StartPoint(), ln2.EndPoint()); AcGePoint3dArray gripPoints; AcDbIntArray ar; if (subGetGripPoints(gripPoints, ar, ar) == Acad::eOk && gripPoints.length() >= 4) { TADSGePoint3d ptGrip=gripPoints[3]; ptGrip.z=0; segMid.SetElevation(0.0); int nSideGrip = segMid.OnWhichSide(ptGrip); TADSGePoint3d ptMid; if (dWallThick / 2.0 - dOffsetDist > -_DIST_SNAP) { ptMid = cv1.MidPoint(); } else { ptMid = cv2.MidPoint(); } int nSide1 = segMid.OnWhichSide(ptMid); if ((m_nOpStyle&OPS_DOORLINE1)) { if(nSide1 != nSideGrip) { dc << cv2; } else { dc << cv1; } } if (m_nOpStyle&OPS_DOORLINE2) { if(nSide1 != nSideGrip) { dc << cv1; } else { dc << cv2; } } } } OPENOBJ_END(); } bool TDbOpening::IsClipMe(const TEntityBase* pEnt)const { // 在此进行CAD平台判断 //TCHAR strVer[20]; //TGGetVar(_T("ACADVER"), strVer); //CString str = strVer; //str = str.Left(4); //if (_T("19.1") == str) // 如果是 cad2014 则退出 // return false;//wlw cad2014崩溃 if(TDbEntity::IsClipMe(pEnt)) return true; if(GetKind()==OP_PROWIN) { if(pEnt->GetMe()->isKindOf(TDbColumn::desc())||//柱裁剪 pEnt->GetMe()->isKindOf(TDbWallPatch::desc()))//墙体造型裁剪 return true; TDbWall*pWall=TDbWall::cast(pEnt->GetMe()); if(pWall!=NULL) { if(pWall->GetUsageFlag()!=TDbWall::kVirtual&&//不是虚墙 GetWallId()!=pWall->objectId())//不在墙上 return true; return false; } } return false; } Acad::ErrorStatus TDbOpening::GetClipBoundary(XPoly2D& poly)const { if (GetKind()==OP_PROWIN && m_pBayWin!=NULL) { OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall); if (pWall) { XPoint ptLoc = m_ptLocation; ptLoc.z = m_ptLocation.z; double nWallThick = pWall->GetWidth(4); double nExtDir = m_nRotation + (m_nQuadrant<2? PI/2.0 : -PI/2.0); // add by xlc on 110624 解决墙上有保温时梯形凸窗,三角凸窗,圆弧凸窗裁剪散水出错的问题 if (m_pBayWin) { if (m_pBayWin->m_nStyle == XBayWindow::BWS_TRIANGLE || m_pBayWin->m_nStyle == XBayWindow::BWS_TRAPEZIA || m_pBayWin->m_nStyle == XBayWindow::BWS_ARC) { TADSGePoint3d ptDir; ads_polar(ptLoc, nExtDir, 10000, ptDir); int nSide = pWall->OnWhichSide(ptDir); // 得到保温厚度 if (pWall->IsInsulateOnSide(nSide)) { double dWallInsut = pWall->GetInsulateThick(nSide); nWallThick = (nWallThick*0.5-dWallInsut)*2; } } } extern Acad::ErrorStatus GetClipBoundary(const XBayWindow*pBayWin,XPoint ptLoc, double nExtDir, double nWidth, double nWallThick,double nSlabThick,BOOL bLeftSlab,BOOL bRightSlab,XPoly2D &poly2d); return GetClipBoundary(m_pBayWin, ptLoc, nExtDir, m_nWidth, nWallThick, m_nProWinSlabWidth, HasLeftSlab(), HasRightSlab(), poly); } OPENOBJ_END(); } return Acad::eInvalidInput; } ///////////////////////////////////////////////////// // 炸碎或者显示二维 // ACAD2002才支持,显示图块之后还可以显示其他图元 // 高窗另存旧版有问题 Acad::ErrorStatus TDbOpening::ExplodeOrDraw2d(XExplodeDraw &dc) const { extern TARCH_IMPEXP BOOL g_bEnableCornWinWarning; dc.SetStyle(m_idTextStyle); BOOL bIsInsu = TRUE; if (!objectId() && !!m_nIdOfWall && _tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0) { // 拖曳 XCurveSegment seg; GetCenterCurve(seg); // extern double g_nAcadVer; if (g_nAcadVer<15.1 || !seg.Is(CURVE_LINE)) DragDraw((XAcGiViewDraw &)dc); } AcDbObjectId idLineDash; TDbConfig *pConfig = NULL; if (g_bSubEntity) // 组合门窗和带型窗 pConfig = GetDwgGlobal(AcDb::kForRead, g_pCurrentDb); else pConfig = GetDwgGlobal(AcDb::kForRead, database()); if (pConfig) { idLineDash = pConfig->GetLinetypeDash(); pConfig->close(); } BOOL bDrawLabel = TRUE; if (IsHighLevel()) { } else if (m_opKind == OP_HOLE) // 绘制洞口示意图 { AcDbObjectId idOldLineType = dc.GetLineTypeId(); dc.SetLineType(idLineDash); XPoly2D poly(1); GetOutlinePoly(0.0, poly); ASSERT(poly.TotalSegments()==4); XCurveSegment seg1, seg2, seg3; poly.Nth(0, seg1); poly.Nth(2, seg2); if (m_nOpStyle&OPS_NOT_BORE) { if (!IsHigh()) dc.SetLineType(idOldLineType); else dc << seg1 << seg2; //垂直于墙的方向的线 // modify by xlc on 110215 增加矩形洞样式 // poly.Nth(IsHigh()? 1 : 3, seg1); // dc << seg1; poly.Nth(IsHigh()? 1 : 3, seg3); if (m_nOpStyle & OPS_POLY_HOLE) // 异型洞 { dc << seg3; } else { if (!(m_nOpStyle & OPS_HOLE_FLAG1) && !(m_nOpStyle & OPS_HOLE_FLAG2)) // 空洞(上下贯通) { dc << seg1 << seg2; // 垂直于墙的方向的线 } else if(!(m_nOpStyle & OPS_HOLE_FLAG1) && (m_nOpStyle & OPS_HOLE_FLAG2)) // 空门洞 { dc.SetLineType(idLineDash); dc << seg3; } else // 高洞,空窗洞 { dc << seg3; } } } else if (!(m_nOpStyle&OPS_HOLE_FLAG1) && !(m_nOpStyle&OPS_HOLE_FLAG2)) // 空洞(上下贯通) dc << seg1 << seg2; // 垂直于墙的方向的线 else if ((m_nOpStyle&OPS_HOLE_FLAG1) && !(m_nOpStyle&OPS_HOLE_FLAG2)) // 空窗洞 { dc.SetLineType(idOldLineType); poly.Nth(1, seg1); poly.Nth(3, seg2); dc << seg1 << seg2; } else if (!(m_nOpStyle&OPS_HOLE_FLAG1) && (m_nOpStyle&OPS_HOLE_FLAG2)) // 空门洞 { // dc << seg1 << seg2; //垂直于墙的方向的线 poly.Nth(1, seg1); poly.Nth(3, seg2); dc << seg1 << seg2; } else // 高洞 dc << seg1 << seg2; // 垂直于墙的方向的线 dc.SetLineType(idOldLineType); } else if (m_opKind == OP_DOORWIN) ExplodeOrDrawDoorWin(dc, FALSE); else if (m_opKind == OP_TWODOOR) ExplodeOrDrawTwoDoor(dc, FALSE); else if (m_opKind == OP_ARCWIN) { // 弧墙上的弧窗 // XDbObject objWall(m_nIdOfWall, AcDb::kForWrite); //modify by xlc on 100528读方式打开,修改时再一些方式打开 XDbObject objWall(m_nIdOfWall, AcDb::kForRead); if (!!objWall) { TDbWall *pDbWall=TDbWall::cast(objWall.m_pObject); ASSERT(pDbWall && pDbWall->Is(CURVE_ARC)); if (pDbWall) { // 弧窗的宽度, 指在墙基线上的宽度 XArc ar=pDbWall->GetArc(); //修改原因 : 增加记录 boundary,hatch 命令涉及到的 动态变换矩阵 m_mat3d // 当AcDbBlockRef 中引用到门窗时,对于boundary,hatch 这样的边界分析命令, // 先调用 transformby,然后调用 ExplodeOrDraw2d时,对关联的墙分析有误,此时 // 墙还没有transformby,导致门窗和墙关系不同步错误,boundary,hatch 分析乱线 // 该矩阵不序列化 //修改人 : lfy 2009-11-08 BOOL bHatch=FALSE; struct resbuf rb; acedGetVar(_T("CMDNAMES"),&rb); CString sCmd = rb.resval.rstring; acutDelString(rb.resval.rstring); if (sCmd.CompareNoCase(_T("BHATCH") ) == 0 || sCmd.CompareNoCase(_T("_BHATCH") ) == 0 || sCmd.CompareNoCase(_T("BOUNDARY")) == 0|| sCmd.CompareNoCase(_T("_BOUNDARY")) == 0) { bHatch=TRUE; } //add by xlc on 110304 解决弧墙上的门窗移动复制时飞线问题 else if (sCmd.CompareNoCase(_T("MOVE")) == 0|| sCmd.CompareNoCase(_T("COPY")) == 0|| sCmd.CompareNoCase(_T("_MOVE")) == 0|| sCmd.CompareNoCase(_T("_COPY")) == 0) { if(!objectId() && !!m_nIdOfWall && _tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0) { bHatch = TRUE; } } if(bHatch) { TADSGePoint3d ptCen = ar.GetCenterPt(); ptCen.TransformBy(m_mat3d); ar.SetCenterPt(ptCen); } double nWallThick=pDbWall->GetWidth(4); XPoint ptLoc=m_ptLocation; ptLoc.z=ar.GetCenterPt().z; XPoint ptOnWall=ptLoc; //修改原因 : 增加记录 boundary,hatch 命令涉及到的 动态变换矩阵 m_mat3d // 当AcDbBlockRef 中引用到门窗时,对于boundary,hatch 这样的边界分析命令, // 先调用 transformby,然后调用 ExplodeOrDraw2d时,对关联的墙分析有误,此时 // 墙还没有transformby,导致门窗和墙关系不同步错误,boundary,hatch 分析乱线 // 该矩阵不序列化 //修改人 : lfy 2009-11-08 if(bHatch) { Acad::ErrorStatus es = pDbWall->upgradeOpen(); //add by xlc on 100528升级打开方式 if (es == Acad::eOk || es == Acad::eWasOpenForWrite) { pDbWall->transformBy(m_mat3d); } else { bHatch = FALSE; //add by xlc on 100625不是写方式打开时不进行变换 } } pDbWall->ProjectToMe(ptLoc, ptOnWall); if(bHatch) { AcGeMatrix3d matInv = m_mat3d; matInv.invert(); pDbWall->assertWriteEnabled(); pDbWall->transformBy(matInv); pDbWall->downgradeOpen(); } double nRad=ads_distance(ar.GetCenterPt(), ptOnWall); double nSweepAng=m_nWidth/nRad; double nStartAng=CT_std_angle(ads_angle(ar.GetCenterPt(), ptOnWall)-nSweepAng/2.0), nEndAng=CT_std_angle(ads_angle(ar.GetCenterPt(), ptOnWall)+nSweepAng/2.0); XArc arMid(ar.GetCenterPt(), ads_distance(ar.GetCenterPt(), ptLoc), nStartAng, nEndAng); TADSGePoint3d ptTmp = arMid.GetCenterPt(); ptTmp.z = 0.0; arMid.SetCenterPt(ptTmp); AcDbObjectId idOldLineType=dc.GetLineTypeId(); if(IsHigh() ) dc.SetLineType(idLineDash); /* if (GetPScale()>g_nCurtainWall3Scale+1.0E-3) dc << arMid; else dc << arMid.Offset(nWallThick/6.0) << arMid.Offset(-nWallThick/6.0); */ // sg modify 090609,带形窗根据样式绘制 if (g_bCurtainWallFixStyle) // 固定样式 { if (g_nCurtainWallStyle == 0) // 固定为三线 dc<g_nCurtainWall3Scale+1.0E-3) dc<GetWallFlag()&WF_LEFTEXT)==0) dc << arMid.Offset(-nWallThick/2.0); else dc << arMid.Offset(nWallThick/2.0); } else if(!IsHigh()) dc << arMid.Offset(nWallThick/2.0)<< arMid.Offset(-nWallThick/2.0); else { XArc ar1=arMid.Offset(nWallThick/2.0); XArc ar2=arMid.Offset(-nWallThick/2.0); XPoint ptVert[4]; ar1.GetStartPoint(ptVert[0]); ar1.GetEndPoint(ptVert[1]); ar2.GetStartPoint(ptVert[2]); ar2.GetEndPoint(ptVert[3]); dc << XLine(ptVert[0], ptVert[2]) << XLine(ptVert[1], ptVert[3]); } dc.SetLineType(idOldLineType); } } else // 画个示意图 { XPoly2D polyShow(1); GetOutlinePoly(0.0, polyShow); dc << polyShow; } } else if (m_opKind == OP_CORNWIN) // 转角窗 { if (!m_nIdOfWall) { if(g_bEnableCornWinWarning) dc.DrawText(_T("请纠正无墙带形窗!")); } else DrawBanWin(dc, FALSE); } else if (m_opKind==OP_PROWIN) // 凸窗 DrawBayWindow2d(dc); else if (!!m_nIdStyle2d && (m_opKind==OP_DOOR || m_opKind==OP_WINDOW)) // 普通门窗 { // 用图块表示的门窗 AcDbObjectId idOldLineType = dc.GetLineTypeId(); if(IsHigh() ) dc.SetLineType(idLineDash); if (IsHigh()) { XPoint ptBack, ptFront; GetSidePoints(ptBack, ptFront); double nWidth = GetWallThickness(TRUE); XCurveSegment segCen(ptBack, ptFront, 0.0); double nDirection = ads_angle(ptBack, ptFront); XPoint ptSide[4]; ads_polar(ptFront, nDirection+PI/2, nWidth/2, ptSide[0]); ads_polar(ptFront, nDirection-PI/2, nWidth/2, ptSide[1]); ads_polar(ptBack, nDirection+PI/2, nWidth/2, ptSide[2]); ads_polar(ptBack, nDirection-PI/2, nWidth/2, ptSide[3]); dc << segCen.Offset(OFFSET_LEFT, nWidth/6.0, LS_FINITE) << segCen.Offset(OFFSET_RIGHT, nWidth/6.0, LS_FINITE) << XCurveSegment(ptSide[0], ptSide[1], 0.0) << XCurveSegment(ptSide[2], ptSide[3], 0.0); } else { BOOL bArcWall=FALSE; XDbObject objWall(m_nIdOfWall, AcDb::kForRead); BOOL bToTch3=(_tcscmp(dc.Desc(), XExplodeStream::Descriptor())==0 &&m_lstClipId.Length()==0//add by whl on 070517,有切割时按绘制走 && dc.IsExportTch4() && m_nIdStyle2d.isValid()); // add by whl on 070515,导出上华3时就不要了,否则会多出很多线 if (m_opKind==OP_WINDOW && !!objWall&& !bToTch3) { TDbWall *pDbWall=TDbWall::cast(objWall.m_pObject); if(pDbWall && pDbWall->Is(CURVE_ARC)) // 弧墙上的弦窗 { if (!HasSlot()) // 假如有门窗套, 则不能绘制 { double nWallThick=pDbWall->GetWidth(4); XPoint ptSide1, ptSide2; GetSidePoints(ptSide1, ptSide2); ptSide1.z=ptSide2.z=0; XCurveSegment segMid=pDbWall->OffsetGeomCenter(LS_FINITE, TRUE); XLine lnMid(ptSide1, ptSide2); /* if(GetPScale()>g_nCurtainWall3Scale+1.0E-3) dc << lnMid; else dc << lnMid.Offset(nWallThick/6.0) << lnMid.Offset(-nWallThick/6.0); */ // sg modify 090609,带形窗根据样式绘制 if (g_bCurtainWallFixStyle) // 固定样式 { if (g_nCurtainWallStyle == 0) // 固定为三线 dc << lnMid; else // 固定四线 dc << lnMid.Offset(nWallThick/6.0) << lnMid.Offset(-nWallThick/6.0); } else // 随比例改变样式 { if (GetPScale()>g_nCurtainWall3Scale+1.0E-3) dc << lnMid; else dc << lnMid.Offset(nWallThick/6.0) << lnMid.Offset(-nWallThick/6.0); } XCurveSegment cv1=segMid.Offset(nWallThick/2.0, LS_FINITE), cv2=segMid.Offset(-nWallThick/2.0, LS_FINITE); XLine ln1=lnMid.Offset(nWallThick/2.0), ln2=lnMid.Offset(-nWallThick/2.0); cv1.SetPoints(ln1.StartPoint(), ln1.EndPoint()); cv2.SetPoints(ln2.StartPoint(), ln2.EndPoint()); dc << cv1 << cv2; } bArcWall=TRUE; } } if (bToTch3) { // 取墙的宽度作为门窗厚度 double nScaleX, nScaleY; GetInsert2DScale(&nScaleX, &nScaleY); XPoint ptInsert=m_ptLocation; ptInsert.z = 0.0; AcDbBlockReference *pInsert=new AcDbBlockReference(ptInsert, m_nIdStyle2d); if(g_bSubEntity)//组合门窗或带型窗 { TMasterProperties prop; dc.BackUpProperties(prop); prop.SetTo(pInsert); } else pInsert->setPropertiesFrom(this); pInsert->setRotation(m_nRotation); AcDbVoidPtrArray entArray; XExplodeStream dcExp(entArray); dcExp.SetAutoProp(FALSE); BOOL bEmptyLab=FALSE; const TCHAR *szLab=(const TCHAR *)m_sLabel; if(!szLab[0]) { szLab=_T("MC"); bEmptyLab=TRUE; } DrawLabel(dcExp, szLab); int num=entArray.length(); if(num==1) { AcDbText *pText=AcDbText::cast((AcDbEntity *)entArray[0]); ASSERT(pText); AcDbAttribute *attr = new AcDbAttribute; attr->setPropertiesFrom(this); attr->setLayer(m_idLayerText); attr->setHeight(pText->height()); TCHAR *szText=pText->textString(); attr->setTextString(bEmptyLab? _T("") : szText); if(szText) delete[] szText; attr->setRotation(pText->rotation()); attr->setHorizontalMode(pText->horizontalMode()); attr->setVerticalMode(pText->verticalMode()); attr->setAlignmentPoint(pText->alignmentPoint()); attr->setTextStyle(pText->textStyle()); attr->setWidthFactor(pText->widthFactor()); attr->setPosition(pText->position()); attr->setTag(_T("A")); VERIFY(pInsert->appendAttribute(attr)==Acad::eOk); bDrawLabel=FALSE; } ReleaseEntSet(entArray); // 没有注册的APPID导致崩溃 AcDbDatabase *pDb=database(); AcDbRegAppTable *pAppTab=NULL; if(pDb) pDb->getSymbolTable(pAppTab, AcDb::kForRead); BOOL bReg=FALSE; if(pAppTab) { bReg=pAppTab->has(_T("WTHICK")); pAppTab->close(); } double nWallWidth=GetWallThickness(TRUE); //Add TRUE argument on 2003/11/10 if(pDb==acdbCurDwg() && bReg) { pInsert->setScaleFactors(AcGeScale3d(nScaleX, nScaleY, nScaleX)); resbuf *xdata=ads_buildlist(1001, _T("WTHICK"), 1040, nWallWidth, NULL); if(pInsert->setXData(xdata)!=Acad::eOk) { //只能对当前图设置 //ASSERT(0); } ads_relrb(xdata); } else pInsert->setScaleFactors(AcGeScale3d(nScaleX, nScaleY, nWallWidth)); // Z比例=墙厚 ((XExplodeStream &)dc).Append(pInsert, FALSE); } else { ///////////////////////////////////////////////////// // 显示图块 if(!bArcWall) { // 取墙的宽度作为门窗厚度 double nScaleX, nScaleY; GetInsert2DScale(&nScaleX, &nScaleY); //构造插入矩阵 XPoint ptInsert=m_ptLocation; ptInsert.z = 0.0; //GetWallElevation(); //二维的位置同墙基的标高 BOOL bMakeBlock=g_bMakeBlock; if(_tcsicmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0) { if (dc.IsPlotGeneration()) // sg add 120507,强制打印时,不使用新方法 bMakeBlock = FALSE; else bMakeBlock=(g_nAcadVer>15.0001); } OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall); if(pWall) { //wlw add 110220 门窗套类型是保温材料时,不画外面的线 BOOL bRightExt = (pWall->GetWallFlag() & WF_LEFTEXT) == 0; if (bRightExt) { if (!pWall->IsInsulateOnSide(OFFSET_RIGHT)) { if (m_nMaterial == 3) {//门窗套类型是保温材料时,不画外面的线 bIsInsu = FALSE; } } else { if (pWall->GetInsulateThick(OFFSET_RIGHT) < 0.01) { if (m_nMaterial == 3) { bIsInsu = FALSE; } } } } else { if (!pWall->IsInsulateOnSide(OFFSET_LEFT)) { if (m_nMaterial == 3) {//门窗套类型是保温材料时,不画外面的线 bIsInsu = FALSE; } } else { if (pWall->GetInsulateThick(OFFSET_LEFT) < 0.01) { if (m_nMaterial == 3) { bIsInsu = FALSE; } } } } } OPENOBJ_END(); if (!DocGetProWinSlabInsu()) {//wlw add 110114 凸窗挡板保温套加保温为FALSE时保温材料的按照普通模式绘制 if (m_nMaterial == 3) { bIsInsu = FALSE; } } if(HasSlot() && m_opKind==OP_WINDOW && !!m_nIdOfWall && bIsInsu) {//有门窗套时要将外边线去除,然后分解绘制 OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall); if(pWall) { //计算门窗套一侧的外边线 XPoint ptStart, ptEnd, ptExtStart,ptExtEnd; GetSidePoints(ptStart, ptEnd); double nExtDirStart=pWall->OrthoDirection(ptStart); double nExtDirEnd=pWall->OrthoDirection(ptEnd); XCurveSegment seg; if((pWall->GetWallFlag()&WF_LEFTEXT)==0) { seg=pWall->GetRelativeSideCurve(OFFSET_RIGHT, pWall->StartPoint(), GetSlotExt()); ads_polar(ptStart, nExtDirStart, pWall->GetWidth(4)/2.0, ptExtStart); ads_polar(ptEnd, nExtDirEnd, pWall->GetWidth(4)/2.0, ptExtEnd); } else { seg=pWall->GetRelativeSideCurve(OFFSET_LEFT, pWall->StartPoint(), GetSlotExt()); ads_polar(ptStart, nExtDirStart+PI, pWall->GetWidth(4)/2.0, ptExtStart); ads_polar(ptEnd, nExtDirEnd+PI, pWall->GetWidth(4)/2.0, ptExtEnd); } seg.SetPoints(ptExtStart, ptExtEnd); seg.SetElevation(0.0); //分解图块后绘制 ads_matrix mat; ConstructMatrix(XPoint(),ptInsert,nScaleX,nScaleY,nScaleX,m_nRotation,mat); AcDbVoidPtrArray entSet; XExplodeStream dc1(entSet); dc1<isKindOf(AcDbLine::desc())) { AcDbLine *pLine=AcDbLine::cast(pEnt); AcGePoint3d pt1=pLine->startPoint(),pt2=pLine->endPoint(); pt1.z=0; pt2.z=0; if((seg.StartPoint()==pt1&&seg.EndPoint()==pt2)|| (seg.StartPoint()==pt2&&seg.EndPoint()==pt1))//端点相同视为外边线,不绘制 continue; } else if(pEnt->isKindOf(AcDbArc::desc())) { AcDbArc *pArc=AcDbArc::cast(pEnt); AcGePoint3d pt1,pt2; pArc->getStartPoint(pt1); pArc->getEndPoint(pt2); pt1.z=0; pt2.z=0; if((seg.StartPoint()==pt1&&seg.EndPoint()==pt2)|| (seg.StartPoint()==pt2&&seg.EndPoint()==pt1))//端点相同视为外边线,不绘制 continue; } pEnt->setLayer(layer()); pEnt->setColorIndex(colorIndex()); dc.DrawEntity(*pEnt); } ReleaseEntSet(entSet); } OPENOBJ_END() } else dc<OrthoDirection(ptStart); double nExtDirEnd=pWall->OrthoDirection(ptEnd); double dWallInsut = 0.0; XCurveSegment seg; if((pWall->GetWallFlag()&WF_LEFTEXT)==0) { seg=pWall->GetRelativeSideCurve(OFFSET_RIGHT, pWall->StartPoint(), GetSlotExt()); if (pWall->IsInsulateOnSide(OFFSET_RIGHT)) { dWallInsut = pWall->GetInsulateThick(OFFSET_RIGHT); if (DocGetProWinSlabInsu()) { dWallInsut -= GetSlotInsulateThick(); } } ads_polar(ptStart, nExtDirStart, GetSlotExt() - dWallInsut +pWall->GetWidth(4)/2.0, ptExtStart); ads_polar(ptEnd, nExtDirEnd, GetSlotExt() - dWallInsut + pWall->GetWidth(4)/2.0, ptExtEnd); } else { if (pWall->IsInsulateOnSide(OFFSET_LEFT)) { dWallInsut = pWall->GetInsulateThick(OFFSET_LEFT); if (DocGetProWinSlabInsu()) { dWallInsut -= GetSlotInsulateThick(); } } seg=pWall->GetRelativeSideCurve(OFFSET_LEFT, pWall->StartPoint(), GetSlotExt()); ads_polar(ptStart, nExtDirStart+PI, GetSlotExt() - dWallInsut + pWall->GetWidth(4)/2.0, ptExtStart); ads_polar(ptEnd, nExtDirEnd+PI, GetSlotExt() - dWallInsut + pWall->GetWidth(4)/2.0, ptExtEnd); } seg.SetPoints(ptExtStart, ptExtEnd); seg.SetElevation(0.0); dc << seg; // if(m_opKind==OP_WINDOW) //{ //绘制玻璃线和里边的墙线 // seg=pWall->GetRelativeOffsetCurveFromCenter(OFFSET_RIGHT, 1.0/6.0, pWall->StartPoint()); // seg.SetElevation(0.0); // XPoint pt1, pt2; // seg.ProjectToMe(ptStart, pt1); // seg.ProjectToMe(ptEnd, pt2); // dc << XLine(pt1, pt2); // seg=pWall->GetRelativeOffsetCurveFromCenter(OFFSET_LEFT, 1.0/6.0, pWall->StartPoint()); // seg.SetElevation(0.0); // seg.ProjectToMe(ptStart, pt1); // seg.ProjectToMe(ptEnd, pt2); // dc << XLine(pt1, pt2); // int nInternalSide = (pWall->GetWallFlag()&WF_LEFTEXT)==0? OFFSET_LEFT : OFFSET_RIGHT; // seg=pWall->GetRelativeSideCurve(nInternalSide, pWall->StartPoint(), 0.0, TRUE); // seg.SetElevation(0.0); // seg.ProjectToMe(ptStart, pt1); // seg.ProjectToMe(ptEnd, pt2); // seg.SetPoints(pt1, pt2); // dc << seg; // } } OPENOBJ_END(); } Acad::ErrorStatus es = Acad::eOk; if (g_bExplodeSubText || (!!m_sLabel&& bDrawLabel)) // bug: 如果设置了图层,则插门的时候出错AcGi-SelectionMarker DrawLabel(dc, m_sLabel); return es; } // Helper functions TSubText* TDbOpening::HitTestText(XPoint pt)const { TSubText* pSubText=TDbEntity::HitTestText(pt); if(pSubText!=NULL) pSubText->SetMenuType(4); return pSubText; } TSubText* TDbOpening::GetSubText(long iText)const { TSubText* pSubText=TDbEntity::GetSubText(iText); if(pSubText!=NULL) pSubText->SetMenuType(4); return pSubText; } void TDbOpening::DrawLabel(XExplodeDraw &dc, const TCHAR *szLab) const { if (!g_bExplodeSubText && (!szLab || !szLab[0] || !IsShowLabel())) return; AcDbObjectId id = m_idTextStyle; if (!id.isValid()) { id = GetTextStyleId(_T("STANDARD"), database()); } ASSERT(id.isValid()); TDbText textLabel; textLabel.setPropertiesFrom(this); if (m_idLayerText.isValid()) textLabel.setLayer(m_idLayerText); //可否设置图层 TPushProperty vProp(&textLabel, dc); //由临时对象设置DC的熟悉 textLabel.SetStyleId(id); textLabel.SetLocation(XPoint(m_ptLabel.x, m_ptLabel.y)); textLabel.SetAlignment(XExplodeDraw::kMiddleCenter); double nRotLabel = Wcs2Layout(m_nRotation); // sg add 110119,标记是否是弧窗 bool bArcWin = 0; if (GetKind()==OP_CORNWIN || GetKind()==OP_ARCWIN) { if (!!m_nIdOfWall) { OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall); if (pWall && pWall->Is(CURVE_ARC)) { XArc ar = pWall->GetArc(); //修改原因 : 增加记录 boundary,hatch 命令涉及到的 动态变换矩阵 m_mat3d // 当AcDbBlockRef 中引用到门窗时,对于boundary,hatch 这样的边界分析命令, // 先调用 transformby,然后调用 ExplodeOrDraw2d时,对关联的墙分析有误,此时 // 墙还没有transformby,导致门窗和墙关系不同步错误,boundary,hatch 分析乱线 // 该矩阵不序列化 //修改人 : lfy 2009-11-08 struct resbuf rb; acedGetVar(_T("CMDNAMES"),&rb); CString sCmd = rb.resval.rstring; acutDelString(rb.resval.rstring); if (sCmd.CompareNoCase(_T("BHATCH") ) == 0 || sCmd.CompareNoCase(_T("_BHATCH") ) == 0 || sCmd.CompareNoCase(_T("BOUNDARY")) == 0|| sCmd.CompareNoCase(_T("_BOUNDARY")) == 0|| //add by xlc on 110304 解决弧墙上的门窗移动复制时飞线问题 sCmd.CompareNoCase(_T("MOVE")) == 0|| sCmd.CompareNoCase(_T("_MOVE")) == 0|| (!objectId()&&(sCmd.CompareNoCase(_T("COPY")) == 0|| sCmd.CompareNoCase(_T("_COPY")) == 0)) ) { TADSGePoint3d ptTmp = ar.GetCenterPt(); ptTmp.TransformBy(m_mat3d);; ar.SetCenterPt(ptTmp); } nRotLabel = CT_std_angle(ads_angle(ar.GetCenterPt(), m_ptLabel) - PI/2); bArcWin = true; // 弧窗 } OPENOBJ_END(); } } // sg modify 110307,解决经过布局旋转后,弧窗标注或者弧墙上的转角窗角度发生变化的情况 if (bArcWin) // 如果是窗标注或者弧墙上的转角窗,需要将根据墙线计算出来的角度,转换为布局转角下的角度 { nRotLabel = Wcs2Layout(m_nRotation); } textLabel.SetRotation(xg_angle(nRotLabel)); textLabel.SetHeight(m_nTextHeight); TCHAR szLabel[256]=_T(""); _tcscpy(szLabel, szLab); TDbConfig *pConfig = GetDwgGlobal(AcDb::kForRead, database()); if (pConfig && pConfig->IsCapLabel()) _tcsupr(szLabel); if (pConfig) pConfig->close(); textLabel.SetText(szLabel); if (dc.IsFullExplode()) { textLabel.ExplodeOrDraw2d(dc); } else dc.DrawEntity(textLabel); } bool TDbOpening::GetNeighbourPoint(XPoint &pt,bool bPre)const { TDbWall *pWall=NULL; OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall0); if (pWall0 != NULL) { pWall=TDbWall::cast(pWall0->clone()); } OPENOBJ_END(); if(pWall==NULL) return false; pWall->RemoveReferenceOpening(objectId()); pt=bPre?pWall->StartPoint():pWall->EndPoint(); XCurveSegment seg; if(pWall->GetSubSegmentAt(m_ptLocation, seg, FALSE)) pt=bPre?seg.StartPoint():seg.EndPoint(); delete pWall; return true; } // 绘制拖动时2D的显示 void TDbOpening::DragDraw(XAcGiViewDraw &dc) const { if(g_bSubEntity) return; extern GEOAPI BOOL GetWcsCursor(XPoint &ptLoc); XPoint ptCursor; TchExport::GetWcsCursor(ptCursor); if(m_idTextStyle.isValid()) dc.SetStyle(m_idTextStyle); else dc.SetStyle(InitTextStyle(TS_WINDOW)); TDbWall *pWall=NULL; OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall0); pWall=TDbWall::cast(pWall0->clone()); OPENOBJ_END(); ASSERT(pWall); XCurveSegment seg; double nTextHeight=PixelToWcs(10); TArchPerDocData*pDocData=GetCurDocData(); if(pDocData!=NULL&&pDocData->m_sCurCommand==_T("GRIP_STRETCH")) { //原始门窗,需要拿掉 AcDbObjectId idThis=GetPrepickEntity(RBList(RTDXF0, _T("ATS_OPENING"), NULL)); if(!!idThis) pWall->RemoveReferenceOpening(idThis); } for(int nSide=0; nSide<2; nSide++) { //0--墙基上的参数,1--墙边上的参数 Adesk::UInt16 nOldColor=dc.GetColor(); dc.SetColor(nSide==0? 1 : 7); BOOL bRet; if(nSide) { bRet=pWall->GetSubSegmentOnSideAt(ptCursor, seg); if(bRet) { XCurveSegment segThis=*pWall; XPoint ptA, ptB; pWall->ProjectToMe(seg.StartPoint(), ptA); pWall->ProjectToMe(seg.EndPoint(), ptB); segThis.SetPoints(ptA, ptB); seg=segThis; } } else bRet=pWall->GetSubSegmentAt(m_ptLocation, seg, FALSE); if(bRet) { XSortedVertexList lstPoints(seg.StartPoint(), seg.EndPoint(), seg.GetBulge()); XPoint pt1, pt2; GetSidePointsOnBase(pt1, pt2); pt1.z=pt2.z=seg.StartPoint().z; int nTextOnSide=0; lstPoints.Insert(pt1); lstPoints.Insert(pt2); if(lstPoints.Length()==4) { XPoly2D poly(0); lstPoints.AsPoly2D(poly); for(int i=0; iOnWhichSide(ptText); dc.SetLocation(ptText); dc.SetAlignment(XExplodeDraw::kMiddleCenter); dc.SetHeight(nTextHeight); dc.SetRotation(xg_angle(nDrt)); double nDispVal=subSeg.GetLength(); XString sDispVal; if(/*g_bDimAngle && */subSeg.Is(CURVE_ARC)) { sDispVal << AS_INT(subSeg.GetBulge()*180.0/PI) << _T("%%d"); } else { sDispVal << AS_INT(nDispVal); } dc.DrawText(sDispVal); } XCurveSegment lCurve, rCurve; if(nSide==1) pWall->GetSideCurve(lCurve, rCurve); for(i=0; i0) { bPrev=TRUE; polyGlass.Nth(i-1, segPrev); nDirPrev=segPrev.IDirection(1); } if(i=0; k--) poly2d.AppendNode(*polyLeft[k]); poly2d.SetElevation(nElev); dc.DrawMesh(poly2d, XVector3D(0,0,m_nHeight)); } } // 其他窗框 if(1) { TDbCurveMesh meshEcs; meshEcs.setPropertiesFrom(this); if(m_idLayerFrame3d.isValid()) meshEcs.setLayer(m_idLayerFrame3d); TPushProperty vProp1(&meshEcs, dc); double nDistPrev=0; XRectAngle boxTemp(XPoint(), m_uFrame, m_vFrame); XPoly2D polySect(1); boxTemp.AsPoly2D(polySect); for(i=0; i ssIn, ssOut,ssEdge; PolyClip(m_lstFrameLines, polyClip, ssIn, ssOut, ssEdge); double nDirNormal=CT_std_angle(seg.IDirection(0)-PI/2); //ECS 法向 BOOL bCircular=seg.Is(CURVE_ARC); XVector3D vtEcs(cos(nDirNormal), sin(nDirNormal), 0.0); //meshEcs.setLayer(dc.GetLayerId()); for(int n=0; nGetWidth(4); double nExtDir = m_nRotation + (m_nQuadrant<2? PI/2.0 : -PI/2.0); ads_polar(ptLoc, nExtDir, 10000, ptDir); double dWallInsut = 0.0; int nSide = pWall->OnWhichSide(ptDir); if (pWall->IsInsulateOnSide(nSide)) // 得到外保温厚度 { dWallInsut = pWall->GetInsulateThick(nSide); } DList polyCurves; m_pBayWin->GetPolyCurve(ptLoc, nExtDir, m_nWidth, nWallThick, HasLeftSlab(), HasRightSlab(), polyCurves, dWallInsut); if (polyCurves.Length() > 1) { polyGlass = *polyCurves[1]; DList lstCurve; ExplodePoly2D(polyGlass, lstCurve); dc.SetColorLayer(colorIndex(), m_idLayerGlass3d); dc.DrawCurveList(lstCurve, m_nHeight); } if ((HasLeftSlab() || HasRightSlab()) && m_pBayWin->m_nStyle==XBayWindow::BWS_RECT) { XPoly2D polyLeft(1),polyRight(1); m_pBayWin->GetVertSlabPoly(ptLoc, nExtDir, m_nWidth, nWallThick, m_nProWinSlabWidth, polyLeft, polyRight); if (HasLeftSlab()) { dc.SetColorLayer(colorIndex(), m_idLayerSlab3d); // wlw add 150611 pc构件增加凸窗板三维显示到墙顶 double dLine = 0.0; m_XDataMap.GetAt(sKEY_OP_PROWIN_LINE, dLine); if (dLine > 0.0) { polyLeft.SetElevation(pWall->StartPoint().z); XVector3D vtUp(0, 0, pWall->GetHeight()); dc.DrawBody(polyLeft, vtUp); } else { polyLeft.SetElevation(ptLoc.z); XVector3D vtUp(0, 0, m_nHeight); dc.DrawBody(polyLeft, vtUp); } } if (HasRightSlab()) { dc.SetColorLayer(colorIndex(), m_idLayerSlab3d); // wlw add 150611 pc构件增加凸窗板三维显示到墙顶 double dLine = 0.0; m_XDataMap.GetAt(sKEY_OP_PROWIN_LINE, dLine); if (dLine > 0.0) { polyRight.SetElevation(pWall->StartPoint().z); XVector3D vtUp(0,0,pWall->GetHeight()); dc.DrawBody(polyRight, vtUp); } else { polyRight.SetElevation(ptLoc.z); XVector3D vtUp(0,0,m_nHeight); dc.DrawBody(polyRight, vtUp); } } polyCurves.Reset(); m_pBayWin->GetPolyCurve(ptLoc, nExtDir, m_nWidth, nWallThick,FALSE,FALSE, polyCurves,dWallInsut); } if (polyCurves.Tail()) { dc.SetColorLayer(colorIndex(), m_idLayerSlab3d); XPoly2D polyOut = *polyCurves.Tail(); polyOut.SetFlag(1); polyOut.SetElevation(ptLoc.z); XVector3D vtUp(0,0,m_nSlabThickness), vtDown(0,0,-m_nSlabThickness); dc.DrawBody(polyOut, vtDown); polyOut.SetElevation(ptLoc.z+m_nHeight); dc.DrawBody(polyOut, vtUp); } dc.SetLayer(idOldLay); dc.SetColor(nOldColor); } OPENOBJ_END(); // 绘制窗框 if (polyGlass.Length()) { DrawFrame3d(dc, polyGlass); } dc.SetLayer(idOldLay); dc.SetColor(nOldColor); return TRUE; } // 绘制圆弧窗 BOOL TDbOpening::DrawArcWin3d(XExplodeDraw &dc) const { Acad::ErrorStatus es=Acad::eOk; XDbObject objWall(m_nIdOfWall, AcDb::kForRead); if(!!objWall) { TDbWall *pDbWall=TDbWall::cast(objWall.m_pObject); ASSERT(pDbWall && pDbWall->Is(CURVE_ARC)); if(pDbWall) { XArc ar=pDbWall->GetArc(); double nWallThick=pDbWall->GetWidth(); XPoint ptLoc=m_ptLocation; TADSGePoint3d ptCen = ar.GetCenterPt(); ptCen.z = ptLoc.z; ar.SetCenterPt(ptCen); XPoint ptOnWall=ptLoc; pDbWall->ProjectToMe(ptLoc, ptOnWall); double nRad=ar.GetCenterPt().Distance2d(ptOnWall); double nSweepAng=m_nWidth/nRad; double nStartAng=CT_std_angle(ads_angle(ar.GetCenterPt(), ptOnWall)-nSweepAng/2.0), nEndAng=CT_std_angle(ads_angle(ar.GetCenterPt(), ptOnWall)+nSweepAng/2.0); XArc arMid(ar.GetCenterPt(), ads_distance(ar.GetCenterPt(), ptLoc), nStartAng, nEndAng); TMasterProperties prop; dc.BackUpProperties(prop); //AcDbObjectId idLay=dc.GetLayerId(); int nOldColor=dc.GetColor(); dc.SetColorLayer(colorIndex(),m_idLayerGlass3d); dc.DrawArc(arMid, m_nHeight); dc.RestoreProperties(prop); XCurveSegment seg; seg=arMid; XPoly2D polyGlass; seg.AsPoly2D(polyGlass); DrawFrame3d(dc, polyGlass); } } else { //画个示意图 XPoly2D polyShow(1); GetOutlinePoly(0.0, polyShow); dc << polyShow; es=Acad::eInvalidInput; } return es; } // 炸碎或者绘制三维门窗 Acad::ErrorStatus TDbOpening::ExplodeOrDraw3d(XExplodeDraw &dc) const { if(!Has3D()) return Acad::eOk; Acad::ErrorStatus es=Acad::eCannotExplodeEntity; //下面代码导致工程管理导出三维实体时洞口被屏蔽,特此注释,但该代码以前的用处并不明朗,如发现其确实有用,再商讨是否打开。2015-7-21 /*if(m_opKind==OxianzaP_HOLE && _tcscmp(dc.Desc(), XExplodeStream::Descriptor())==0) return es;*/ OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall); if(pWall) { if(!g_bIntWall3DVisible && !pWall->IsExternal(OFFSET_LEFT) && !pWall->IsExternal(OFFSET_RIGHT)) return Acad::eOk; //关闭内墙显示 } OPENOBJ_END(); if(!objectId() && !!m_nIdOfWall && _tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0) { //拖曳 DragDraw((XAcGiViewDraw &)dc); } if(m_opKind==OP_HOLE) { XPoly2D poly(1); GetElevOutline(poly); //已经折线化了 dc << poly; return Acad::eOk; } if(m_opKind==OP_ARCWIN) { //弧墙上的弧窗 DrawArcWin3d(dc); } else if(m_opKind==OP_CORNWIN) { //转角窗 DrawBanWin(dc, TRUE); } else if(m_opKind==OP_DOORWIN) { ExplodeOrDrawDoorWin(dc, TRUE); } else if(m_opKind==OP_TWODOOR) { ExplodeOrDrawTwoDoor(dc, TRUE); } else if(m_opKind==OP_PROWIN) { //凸窗 DrawBayWindow3d(dc); } else if(g_bOsnapExpl) { // OSNAP需要加速 XPoly2D poly(1); GetElevOutline(poly); //已经折线化了 dc << poly; } else { if(m_lstFrameLines.Length()) { XPoly2D polyGlass; XCurveSegment segGlass; GetSidePoints(segGlass.StartPoint(), segGlass.EndPoint()); segGlass.AsPoly2D(polyGlass); DrawFrame3d(dc, polyGlass); TMasterProperties prop; dc.BackUpProperties(prop); segGlass.SetElevation(GetElevation()); dc.SetColorLayer(colorIndex(), m_idLayerGlass3d); dc.DrawCurve(segGlass, m_nHeight); dc.RestoreProperties(prop); } else { double nScaleX, nScaleY, nScaleZ; if(GetInsert3DScale(&nScaleX, &nScaleY, &nScaleZ)!=Acad::eOk) return es; AcDbObjectId idStyle=!m_nIdStyle3d? m_nIdStyle2d:m_nIdStyle3d; XPoint ptInsert=m_ptLocation; if(!(!m_nIdStyle3d)) { //显示真三维 dc<Is(CURVE_ARC)); if(pDbWall) { XArc ar=pDbWall->GetArc(); double nWallThick=pDbWall->GetWidth(); XPoint ptLoc=m_ptLocation; TADSGePoint3d ptCen = ar.GetCenterPt(); ptCen.z = ptLoc.z; ar.SetCenterPt(ptCen); XPoint ptOnWall=ptLoc; pDbWall->ProjectToMe(ptLoc, ptOnWall); double nRad=ar.GetCenterPt().Distance2d(ptOnWall); double nSweepAng=m_nWidth/nRad; double nStartAng=CT_std_angle(ads_angle(ar.GetCenterPt(), ptOnWall)-nSweepAng/2.0), nEndAng=CT_std_angle(ads_angle(ar.GetCenterPt(), ptOnWall)+nSweepAng/2.0); XArc arMid(ar.GetCenterPt(), ads_distance(ar.GetCenterPt(), ptLoc), nStartAng, nEndAng); XCurveSegment seg; seg=arMid; seg.AsPoly2D(polyGlass); } } else { return FALSE; } } else if(m_opKind==OP_CORNWIN) { //带形窗 XCurveSegment segLeftSide, segLeft, segMid, segRight, segRightSide; if(!GetBanWinSegs(segLeftSide, segLeft, segMid, segRight, segRightSide)) return FALSE; segMid.AsPoly2D(polyGlass); } else if(m_opKind==OP_DOORWIN) { return FALSE; } else if(m_opKind==OP_TWODOOR) { return FALSE; } else if(m_opKind==OP_PROWIN) { //凸窗 if(!m_pBayWin) return FALSE; DList polyCurves; OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall); if(pWall) { XPoint ptLoc=m_ptLocation,ptDir; ptLoc.z = m_ptLocation.z; double nWallThick=pWall->GetWidth(4); double nExtDir=m_nRotation + (m_nQuadrant<2? PI/2.0 : -PI/2.0); ads_polar(ptLoc, nExtDir, 10000, ptDir); double dWallInsut = 0.0; int nSide = pWall->OnWhichSide(ptDir); //得到外保温厚度 if (pWall->IsInsulateOnSide(nSide)) { dWallInsut = pWall->GetInsulateThick(nSide); } m_pBayWin->GetPolyCurve(ptLoc, nExtDir, m_nWidth, nWallThick,HasLeftSlab(),HasRightSlab(),polyCurves); polyGlass=*polyCurves[1]; } OPENOBJ_END(); } else { //普通门窗 XCurveSegment segLine; GetSidePoints(segLine.StartPoint(), segLine.EndPoint()); segLine.AsPoly2D(polyGlass); } if(!polyGlass) return FALSE; XPoly2D polyOut(1); XPoint ptOut[4]; ptOut[1].x = ptOut[2].x = polyGlass.Distance2d(); ptOut[2].y = ptOut[3].y = m_nHeight; for(int n=0; n<4; n++) polyOut.AppendNode(ptOut[n]); AcDbPolyline *pOutline=new AcDbPolyline; PolyConvert(polyOut, *pOutline); entSetFix.append(pOutline); double nDist=0.0; for(int i=1; i= 0) { pLay = LAY_FIRE_DOOR; } else if (csSubType.Find(_T("防火卷帘")) >= 0) { pLay = LAY_FIRE_JL; } // sg add 111018,增加考虑隔断门在特殊的图层上,以前没有考虑 else if ((m_nOpStyle&OPS_LVTRY) || csSubType.Compare(_T("隔断门"))==0) { pLay = LAY_LATRINE; } else { pLay = LAY_DOOR; } } else if (m_opKind==OP_DOORWIN || m_opKind==OP_TWODOOR) // 门连窗、子母门 pLay = LAY_DOOR; else if (m_opKind == OP_HOLE) // 洞口 pLay = LAY_HOLE2D; else { // sg modify 110217,对防火门、防火卷帘进行了特殊图层设置 CString csSubType = GetSubKind(); // 子类型 if (csSubType.Find(_T("防火窗")) >= 0) { pLay = LAY_FIRE_WIN; } else if (csSubType.Find(_T("防火卷帘")) >= 0) { pLay = LAY_FIRE_JL; } else { CString sKind = GetKindString(); if (sKind.Find(_T("门")) >= 0) pLay = LAY_DOOR; else pLay = LAY_WIN; } } return pLay; } // 设置类型: 门,窗,洞 void TDbOpening::SetKind(OpeningKind opk) { m_opKind=opk; const TCHAR *szLay=NULL; switch(m_opKind) { case OP_HWINDOW: szLay=LAY_DOOR; break; case OP_WINDOW: szLay=LAY_WIN; break; case OP_DOOR: szLay=LAY_DOOR; break; case OP_HOLE: szLay=LAY_HOLE2D; break; } if(szLay) setLayer(szLay); } bool TDbOpening::IsDoorAsWin()const { if(GetKind()!=OP_DOOR) return false; if(!m_nIdStyle2d) return false; OPENOBJ_BEGIN(m_nIdStyle2d, AcDb::kForRead, AcDbBlockTableRecord, pBlock); if(pBlock!=NULL) { // 从扩展实体数据取出原始墙厚 resbuf *pxData=pBlock->xData(TCHXD); if(pxData!=NULL) { resbuf *pNext=pxData->rbnext; if(pNext && pNext->restype==1040) { double nWallThick= pNext->resval.rreal; if(fabs(nWallThick)>1E-6)//这个墙厚只用来判断是不是推拉门 return true; } ads_relrb(pxData); } } OPENOBJ_END(); return false; } Acad::ErrorStatus TDbOpening::GetInsert2DScale(double *pScaleX, double *pScaleY) const { assertReadEnabled(); double nScaleX, nScaleY; nScaleY = GetWallThickness(TRUE); if(m_opKind==OP_DOOR &&!IsDoorAsWin())//add by whl on 050728,不是推拉门等与墙厚有关的门 nScaleY=m_nWidth; nScaleX=m_nWidth; if(m_nQuadrant==1) nScaleX = -nScaleX; else if(m_nQuadrant==2) { nScaleX = -nScaleX; nScaleY = -nScaleY; } else if(m_nQuadrant==3) nScaleY = -nScaleY; *pScaleX = nScaleX; *pScaleY = nScaleY; return Acad::eOk; } /////////////////////////////////////////////////////////// // static 求3D图块的原始尺寸 BOOL TDbOpening::GetOriginal3DSize(AcDbObjectId idStyle3d, XPoint &sizeXYZ) { if(!idStyle3d) return FALSE; BOOL nRet=FALSE; OPENOBJ_BEGIN(idStyle3d, AcDb::kForRead, AcDbBlockTableRecord, pBlock); if(!pBlock) return FALSE; // 从扩展实体数据取出原始尺寸 resbuf *pxData=pBlock->xData(TCHXD); if(!pxData) { AcDbBlockReference entInsert; entInsert.setBlockTableRecord(idStyle3d); AcDbExtents ext; if(entInsert.getGeomExtents(ext)!=Acad::eOk) return FALSE; AcGePoint3d ptMax=ext.maxPoint(), ptMin=ext.minPoint(); double sx=ptMax.x-ptMin.x; double sz=ptMax.z-ptMin.z; if(sx<_DIST_SNAP || sz<_DIST_SNAP) return FALSE; sizeXYZ=XPoint(sx,60.0,sz); nRet=TRUE; } else { resbuf *pNext=pxData->rbnext; if(pNext && pNext->restype==1040) { double sx = pNext->resval.rreal; pNext=pNext->rbnext; if(pNext && pNext->restype==1040) { double sz = pNext->resval.rreal; ASSERT(sx>_DIST_SNAP && sz>_DIST_SNAP); sizeXYZ = XPoint(sx,60.0,sz); nRet = TRUE; } } ads_relrb(pxData); } OPENOBJ_END(); return nRet; } // 求3D插入比例 Acad::ErrorStatus TDbOpening::GetInsert3DScale(double *pScaleX, double *pScaleY, double *pScaleZ) const { assertReadEnabled(); double nScaleX, nScaleY, nScaleZ; if(!(!m_nIdStyle3d)) { // Use 3dStyle XPoint origenalSize; if(!GetOriginal3DSize(m_nIdStyle3d, origenalSize)) return Acad::eInvalidInput; nScaleX = origenalSize.x>_DIST_SNAP? (m_nWidth/origenalSize.x) : 1.0; nScaleY = origenalSize.y>_DIST_SNAP? (m_nThickness/origenalSize.y) : 1.0; nScaleZ = origenalSize.z>_DIST_SNAP? (m_nHeight/origenalSize.z) : 1.0; if(origenalSize.y>origenalSize.x/2.0) //旋转门 nScaleY=nScaleX; else nScaleY=1.0; } else { // Use 2d Extrude XDbObject objBlock(m_nIdStyle2d, AcDb::kForRead); if(!objBlock) return Acad::eInvalidInput; AcDbBlockTableRecord *pBlock = AcDbBlockTableRecord::cast(objBlock.m_pObject); if(m_opKind==OP_DOOR) nScaleY=m_nWidth; else nScaleY=GetWallThickness(); nScaleX=m_nWidth; nScaleZ=1.0; } // 镜像情况 if(m_nQuadrant==1) nScaleX = -nScaleX; else if(m_nQuadrant==2) { nScaleX = -nScaleX; nScaleY = -nScaleY; } else if(m_nQuadrant==3) nScaleY = -nScaleY; *pScaleX = nScaleX; *pScaleY = nScaleY; *pScaleZ = nScaleZ; return Acad::eOk; } // 把门窗插入墙内 Acad::ErrorStatus TDbOpening::InsertIntoWall(TDbWall *pWall) { assertWriteEnabled(); m_nRotation = pWall->Direction(m_ptLocation); //m_nThickness = pWall->GetWidth(); XPoint ptNewLoc; pWall->GetOpeningLocation(m_ptLocation, GetKind(), m_nWidth, ptNewLoc); m_ptLocation = ptNewLoc; m_nIdOfWall = pWall->objectId(); AcDbObjectId idTextStyle = m_idTextStyle; // if(!idTextStyle.isValid()) idTextStyle=InitTextStyle(TS_WINDOW,database()); XDbObject objTextStyle(idTextStyle, AcDb::kForRead); ads_real nDistToLocation=pWall->GetWidth(); if(!objTextStyle) ; else { AcDbTextStyleTableRecord *pTextStyle=AcDbTextStyleTableRecord::cast(objTextStyle.m_pObject); if(pTextStyle) nDistToLocation += pTextStyle->textSize()*GetPScale(); } //门的标号搁到开向的另一侧,窗总搁到外侧 /* ads_real nExtDrt = pWall->ExtDirection(m_ptLocation); ads_real nDrtLabel= CT_std_angle(nExtDrt+PI); ads_polar(m_ptLocation, nDrtLabel, nDistToLocation, m_ptLabel); m_ptLabel.z = 0; */ double nWallWidth=pWall->GetWidth(); nDistToLocation=nWallWidth/2; double nDist2Wall=GetTextHeight()/2; nDist2Wall += DocGetText2Base(); nDistToLocation += nDist2Wall*GetPScale(); XPoint ptLab; ads_polar(m_ptLocation, m_nRotation+(m_nQuadrant>=2? 1.0 : -1.0)*PI/2, nDistToLocation, ptLab); ptLab.z = 0; m_ptLabel= ptLab; return Acad::eOk; } XPoint TDbOpening::GetDefaultLabPos() const { double nWallWidth=GetWallThickness(TRUE); ads_real nDistToLocation=nWallWidth/2; double nDist2Wall=GetTextHeight()/2; nDist2Wall += DocGetText2Base(); nDistToLocation += nDist2Wall*GetPScale(); XPoint ptLab; ads_polar(m_ptLocation, m_nRotation+(m_nQuadrant>=2? 1.0 : -1.0)*PI/2, nDistToLocation, ptLab); ptLab.z = 0; return ptLab; } // 验证调整和墙的配属关系 // 方法: 如果有配属的墙则验证是否成立配属关系; 否则寻找一配属墙,确立新的关系 // 注意: 在命令结束时处理 void TDbOpening::ValidateContainership(DList &lstWalls) { assertWriteEnabled(); // add by xlc on 110131 普通的独立门窗不进行验证 if ((m_opKind == OP_DOOR || m_opKind == OP_WINDOW) && IsLoneOpening()) { return; } if(!(!m_nIdOfWall)) { //验证原来的配属关系是否成立 XDbObject obj(m_nIdOfWall, AcDb::kForRead); if(!(!obj)) { TDbWall *pWall = TDbWall::cast(obj.m_pObject); if(pWall) { if(!pWall->CanContain(*this)) { if(pWall->upgradeOpen()==Acad::eOk) { pWall->assertWriteEnabled(); ::RemoveContainership(pWall, this); pWall->downgradeOpen(); } } else { //确保互相引用关系 AcDbObjectId __id = objectId(); if(!pWall->m_lstOpeningId.FindNode(&__id, CompareObjectId)) { if(pWall->upgradeOpen()==Acad::eOk) { pWall->assertWriteEnabled(); pWall->m_lstOpeningId.Append(new AcDbSoftPointerId(objectId())); pWall->downgradeOpen(); } } XPoint ptLoc; if(pWall->GetOpeningLocation(m_ptLocation, GetKind(), GetWidth(), ptLoc)) { m_ptLocation=ptLoc; ptLoc.z = pWall->GetElevation(); double nWallDirection = pWall->Direction(ptLoc); double nDirectionOld=m_nRotation; m_nRotation=nWallDirection; //计算相对角(<=PI) double nA=CT_std_angle(m_nRotation-nDirectionOld); if(nA>PI) nA=PI*2-nA; if(nA>(PI/2+1E-6))//墙方向与当前方向夹角大于90度时,尽量维持原开启方向 { if(m_nQuadrant==0) m_nQuadrant=2; else if(m_nQuadrant==2) m_nQuadrant=0; else if(m_nQuadrant==1) m_nQuadrant=3; else m_nQuadrant=1; } } } } } } // 如果没有配属关系,则重新建立 if(!m_nIdOfWall) { for(int i=0; iCanContain(*this)) { XPoint ptOld=m_ptLabel; double nDirectionOld=m_nRotation; pWall->InsertOpening(this); resbuf *xdata=xData(_T("TDOTE")); if(xdata && xdata->rbnext && xdata->rbnext->restype==1010) { //转换旧图 XPoint ptData=xdata->rbnext->resval.rpoint; if(CT_IsExactSameDrt(ptData.z, m_nRotation, _angSnap)) { if(ptData.x>0) { if(ptData.y>0) m_nQuadrant=0; else m_nQuadrant=3; } else { if(ptData.y>0) m_nQuadrant=1; else m_nQuadrant=2; } } else { ptData.x = - ptData.x; ptData.y = - ptData.y; if(ptData.x>0) { if(ptData.y>0) m_nQuadrant=0; else m_nQuadrant=3; } else { if(ptData.y>0) m_nQuadrant=1; else m_nQuadrant=2; } } if(xdata->rbnext) ads_relrb(xdata->rbnext); xdata->rbnext=NULL; m_ptLabel=ptOld; setXData(xdata); ads_relrb(xdata); } else { //modified by whl on 070611 //计算相对角(<=PI) double nA=CT_std_angle(m_nRotation-nDirectionOld); if(nA>PI) nA=PI*2-nA; if(nA>(PI/2+1E-6))//墙方向与当前方向夹角大于90度时,尽量维持原开启方向 { if(m_nQuadrant==0) m_nQuadrant=2; else if(m_nQuadrant==2) m_nQuadrant=0; else if(m_nQuadrant==1) m_nQuadrant=3; else m_nQuadrant=1; } if(CT_IsSameDrt(nDirectionOld, m_nRotation, _angSnap))//墙方向不变时,编号位置不变,否则成为默认位置 m_ptLabel=ptOld; } break; } } } } void TDbOpening::ValidateDim(DList &lstDims) { if(lstDims.Length()<1) return; assertWriteEnabled(); bool bErased=isErased()==Adesk::kTrue; XPoint ptNew0,ptNew1; GetSidePoints(ptNew0,ptNew1); for(long i=0;iownerId()==ownerId()&&//add by whl on 060829,属于同一块内 !pDim->IsAngular()&&pDim->IsAssociate()) pDim->UpdateFrom(ptNew0,ptNew1,m_ptBackOld,m_ptFrontOld,bErased); pDim->close(); } } } void TDbOpening::MirrorSelf(BOOL bLeftRight) //左右镜像或上下进行 { assertWriteEnabled(); int nQua=m_nQuadrant; switch(nQua) { case 0: nQua=bLeftRight? 1 : 3; break; case 1: nQua=bLeftRight? 0 : 2; break; case 2: nQua=bLeftRight? 3: 1; break; case 3: nQua=bLeftRight? 2 : 0; break; } m_nQuadrant=nQua; if(!bLeftRight) { //编号位置镜像 XLine ln(m_ptLocation, m_nRotation); ln.SetElevation(m_ptLabel.z); XPoint ptPrj; if(m_ptLabel.Project(&ln, ptPrj)==RTNORM) { ptPrj.Mirror(XPoint(m_ptLabel), m_ptLabel); } //add by xlc on 110215 调整单侧门口线开启侧 if (!( (m_nOpStyleEx & OPS_DOORLINE_MID) //居中 || (m_nOpStyle & (OPS_DOORLINE1+OPS_DOORLINE2)) == 0 //无门口线 || (m_nOpStyle | (OPS_DOORLINE1+OPS_DOORLINE2)) == m_nOpStyle //双侧门口线 ) ) { if (m_nOpStyle & OPS_DOORLINE1) { m_nOpStyle &= ~OPS_DOORLINE1; } else { m_nOpStyle |= OPS_DOORLINE1; } if (m_nOpStyle & OPS_DOORLINE2) { m_nOpStyle &= ~OPS_DOORLINE2; } else { m_nOpStyle |= OPS_DOORLINE2; } } } } /* * * * * * * * * * 取 动 态 属 性 显 示 数 据 的 函 数 * * * * * * * * * */ void TDbOpening::GetTips(DList &lstInfo) const { //add by whl AcDbHandle h; getAcDbHandle(h); TCHAR pBuf[1024]; h.getIntoAsciiBuffer(pBuf); lstInfo.Append(new TObjInfoUnit(_T("对象句柄"), pBuf)); XString sName=GetKindString(); lstInfo.Append(new TObjInfoUnit(_T("门窗类型"), sName)); lstInfo.Append(new TObjInfoUnit(_T("门窗编号"), m_sLabel)); lstInfo.Append(new TObjInfoUnit(_T("宽度"), Dist2Str(m_nWidth))); lstInfo.Append(new TObjInfoUnit(_T("高度"), Dist2Str(m_nHeight))); lstInfo.Append(new TObjInfoUnit(_T("离地高度"), Dist2Str(m_ptLocation[2]))); lstInfo.Append(new TObjInfoUnit(_T("转角"), Angle2Str(m_nRotation*180.0/PI))); lstInfo.Append(new TObjInfoUnit(_T("洞墙面积比"), XString(_T("%.3f"), GetAreaIndex()))); } //只能用于当前图对象,设置缺省子图层和文字样式 void TDbOpening::InitHardPointerId() { m_idTextStyle=InitTextStyle(TS_WINDOW); m_idLayerFrame3d=InitLayer(LAY_3DFRAME, FALSE); m_idLayerGlass3d=InitLayer(LAY_3DGLASS, FALSE); m_idLayerSlab3d=InitLayer(LAY_WALL, FALSE); // sg modify 110223,防火门、防火窗、防火卷帘中的门窗标注单独存放一个图层 // m_idLayerText=InitLayer(LAY_OPENING_DIM, FALSE); if (m_opKind==OP_DOOR || m_opKind==OP_WINDOW || m_opKind==OP_ARCWIN) { CString csSubType = GetSubKind(); // 子类型 if (csSubType.Find(_T("防火门"))>=0 || csSubType.Find(_T("防火卷帘"))>=0 || csSubType.Find(_T("防火窗"))>=0) { m_idLayerText=InitLayer(LAY_FILEOPENING_DIM, FALSE); } else { m_idLayerText=InitLayer(LAY_OPENING_DIM, FALSE); } } else { m_idLayerText=InitLayer(LAY_OPENING_DIM, FALSE); } TDbConfig *pConfig=GetDwgGlobal(AcDb::kForWrite,g_pCurrentDb); if(pConfig) pConfig->close(); } /* ----------------------------------------------------------------------- */ void TDbOpening::UpdateOwnerWallGraphic() const { if(!!m_nIdOfWall) { PickSet ss(SS_FREE); ss += m_nIdOfWall; UpdateGraphic(ss); } } //-------------------------------------------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////////////////////////////////////////// // 节能属性 //窗墙面积比:>0正常,其他为错误发生 double TDbOpening::GetAreaIndex() const { double nRatio=0.0; OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall); if(pWall && pWall->IsValid()) { XCurveSegment segCen=pWall->OffsetGeomCenter(LS_FINITE, TRUE); double nAreaWall=_AS_METER(segCen.GetLength())*_AS_METER(pWall->GetHeight())*pWall->GetShapeRatio(); double nAreaWin=_AS_SQMETER(GetOutlineArea()); nRatio=nAreaWin/nAreaWall; } OPENOBJ_END(); return nRatio; } //求方位角:弧窗取中心点的朝向 //弧度:>=0正常,<0错误发生:如内门窗等 double TDbOpening::GetAzimuth() const { double nAzimuth=-1.0; OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall); if(pWall && pWall->IsValid()) { int nSide=pWall->GetExtSide(); if(nSide==0 || nSide==1) { nAzimuth=pWall->GetAzimuth(nSide, m_ptLocation); } } OPENOBJ_END(); return nAzimuth; } ////////////////////////////////////////////////////////////////////////////////////////////////////////// //-------------------------------------------------------------------------------------------------------- #if 0 /////////////////////////////////////////////////////////////////// // 通过量化属性取得属性量 Acad::ErrorStatus TDbOpening::GetQuantumByName(const TCHAR *pszName, double *pQuantum) const { ASSERT(pszName && pQuantum); Acad::ErrorStatus es = Acad::eOk; double nRes=0.0; if(_tcscmp(pszName, OP_QUANTUM_1)==0) { nRes = AS_METER(GetOutlineLength()); } else if(_tcscmp(pszName, OP_QUANTUM_2)==0) { nRes = _AS_SQMETER(GetOutlineArea()); } else if(_tcscmp(pszName, OP_QUANTUM_3)==0) { nRes = AS_METER(GetWidth()); } else { es = Acad::eInvalidInput; } *pQuantum = nRes; return es; } /////////////////////////////////////////////////////////// // 初始化注册量化的属性名字 void TDbOpening::InitQuantumProtocol(BOOL bTrue) { static XQuantumProtocol *pProtocol=NULL; if(bTrue) { pProtocol=new XQuantumProtocol; pProtocol->m_lstQuantumNames.Append(strnew(OP_QUANTUM_1)); pProtocol->m_lstQuantumNames.Append(strnew(OP_QUANTUM_2)); pProtocol->m_lstQuantumNames.Append(strnew(OP_QUANTUM_3)); desc()->addX(XQuantumProtocol::desc(), pProtocol); } else { desc()->delX(XQuantumProtocol::desc()); delete pProtocol; pProtocol = NULL; } } void TDbOpening::InitProperty(BOOL bTrue) { m_lstProperties.Reset(); if(!bTrue) return; m_lstProperties.Append(new XAccessObjectProperty(/*UMSG*/_T("类别"), (PropertyFun)AccessKind, FALSE)); m_lstProperties.Append(new XAccessObjectProperty(/*UMSG*/"编号", (PropertyFun)AccessLabel, TRUE)); m_lstProperties.Append(new XAccessObjectProperty( /*UMSG*/"宽度,(mm)", (PropertyFun)AccessWidth, TRUE, VT_I4, "%d")); m_lstProperties.Append(new XAccessObjectProperty( /*UMSG*/"高度,(mm)", (PropertyFun)AccessHeight, TRUE, VT_I4, "%d")); m_lstProperties.Append(new XAccessObjectProperty( /*UMSG*/"厚度,(mm)", (PropertyFun)AccessThickness, TRUE, VT_I4, "%d")); m_lstProperties.Append(new XAccessObjectProperty( /*UMSG*/"窗台高度,(mm)", (PropertyFun)AccessSill, TRUE, VT_I4, "%d")); m_lstProperties.Append(new XAccessObjectProperty( /*UMSG*/"面积,(m^2)", (PropertyFun)AccessArea, FALSE, VT_R8, "%6.2f")); m_lstProperties.Append(new XAccessObjectProperty( /*UMSG*/"周长,(mm)", (PropertyFun)AccessPerimeter, FALSE, VT_I4, "%d")); } #endif void InitDbOpening(BOOL bTrue) { if(bTrue) { TDbOpening::rxInit(); acrxBuildClassHierarchy(); TDbOpening::InitMatchProtocol(TRUE); //TDbOpening::InitProperty(TRUE); //TDbOpening::InitQuantumProtocol(TRUE); } else { //TDbOpening::InitQuantumProtocol(FALSE); //TDbOpening::InitProperty(FALSE); TDbOpening::InitMatchProtocol(FALSE); deleteAcRxClass(TDbOpening::desc()); } } TARCH_IMPEXP void CheckOp3dStyle(AcDbObjectId idStyle3d) { AssureLayer(LAY_KEY, LAYSTAT_UNLOCK); OPENOBJ_BEGIN(idStyle3d, AcDb::kForWrite, AcDbBlockTableRecord, pBlockRec); if(pBlockRec) { resbuf *rbxdOld=pBlockRec->xData(TCHXD); if(!rbxdOld) { BOOL bSetXD=FALSE; XPoint ptMin, ptMax; BOOL bInitExt=FALSE; XString sBoundHandle; RBList rbPointMask(RTDXF0, _T("POINT"), 8, LAY_KEY, 62, 1, NULL); RBList rbBoundMask(RTDXF0, _T("LWPOLYLINE,POLYLINE"), 8, LAY_BOUNDARY, 70, 1, NULL); RBList rbShadeMask(8, _T("ASHADE"), NULL); RBList rbMaterMask(RTDXF0,_T("INSERT"),2, _T("RM_SDB"), NULL); //遍历块表记录,寻找轮廓的POLYLINE AcDbBlockTableRecordIterator* pBlockIterator=NULL; VERIFY(pBlockRec->newIterator(pBlockIterator)==Acad::eOk); for (pBlockIterator->start(); !pBlockIterator->done(); pBlockIterator->step()) { AcDbEntity *pEntity; VERIFY(pBlockIterator->getEntity(pEntity, AcDb::kForRead)==Acad::eOk); Entity ent; acdbGetAdsName(ent.name, pEntity->objectId()); if(ent.MatchBase(rbPointMask)) { resbuf *rbxd=pEntity->xData(TCHXD); if(pEntity->upgradeOpen()==Acad::eOk) { pEntity->erase(); pEntity->downgradeOpen(); } if(rbxd) { pBlockRec->setXData(rbxd); ads_relrb(rbxd); bSetXD=TRUE; pEntity->close(); break; } } else if(ent.MatchBase(rbBoundMask)){ ent.GetData(5, (TCHAR *)sBoundHandle); } else if(ent.MatchBase(rbShadeMask)) { } else if(ent.MatchBase(rbMaterMask)) { } else { XPoint pt1, pt2; if(ent.GetExtend(pt1, pt2)==RTNORM) { if(!bInitExt) { ptMin=pt1; ptMax=pt2; } else { ptMin=Min(ptMin, pt1); ptMax=Max(ptMax, pt2); } bInitExt=TRUE; } } pEntity->close(); } delete pBlockIterator; if(!bSetXD && bInitExt) { XVector3D vtSize=ptMax-ptMin; resbuf *rbxd=NULL; if(!sBoundHandle) rbxd=ads_buildlist(1001, TCHXD, 1040, vtSize.x, 1040, vtSize.z,NULL); else rbxd=ads_buildlist(1001, TCHXD, 1040, vtSize.x, 1040, vtSize.z, 1005, (const TCHAR *)sBoundHandle, NULL); if(!XSymbolTable(_T("APPID"), TCHXD)) ads_regapp(TCHXD); pBlockRec->setXData(rbxd); ads_relrb(rbxd); } } else { ads_relrb(rbxdOld); } } OPENOBJ_END(); AssureLayer(LAY_KEY, LAYSTAT_LOCK); } TARCH_IMPEXP void CheckOp2dStyle(AcDbObjectId idStyle2d) { AssureLayer(LAY_KEY, LAYSTAT_UNLOCK); OPENOBJ_BEGIN(idStyle2d, AcDb::kForWrite, AcDbBlockTableRecord, pBlockRec); if(pBlockRec) { resbuf *rbxdOld=pBlockRec->xData(TCHXD); if(!rbxdOld) { BOOL bSetXD=FALSE; RBList rbPointMask(RTDXF0, _T("POINT"), 8, LAY_KEY, 62, 1, NULL); AcDbBlockTableRecordIterator* pBlockIterator=NULL; VERIFY(pBlockRec->newIterator(pBlockIterator)==Acad::eOk); for (pBlockIterator->start(); !pBlockIterator->done(); pBlockIterator->step()) { AcDbEntity *pEntity; VERIFY(pBlockIterator->getEntity(pEntity, AcDb::kForRead)==Acad::eOk); Entity ent; acdbGetAdsName(ent.name, pEntity->objectId()); if(ent.MatchBase(rbPointMask)) { resbuf *rbxd=pEntity->xData(TCHXD); if(pEntity->upgradeOpen()==Acad::eOk) { pEntity->erase(); pEntity->downgradeOpen(); } if(rbxd) { pBlockRec->setXData(rbxd); ads_relrb(rbxd); bSetXD=TRUE; pEntity->close(); break; } } pEntity->close(); } delete pBlockIterator; } else ads_relrb(rbxdOld); } OPENOBJ_END(); AssureLayer(LAY_KEY, LAYSTAT_LOCK); } // 门窗套材料 int TDbOpening::GetSlotMaterial() const { double dThick = 0.0; int nMat = 0; BOOL bSlotInsCap = TRUE; ReadInsulateFromXData(nMat, dThick,bSlotInsCap); return nMat; } void TDbOpening::SetSlotMaterial(int nMat) { double dThick = 0.0; int nMatT = 0; BOOL bSlotInsCap = TRUE; ReadInsulateFromXData(nMatT, dThick,bSlotInsCap); WriteInsulateToXData(nMat,dThick,bSlotInsCap); //wlw add 100913 m_nMaterial = nMat; } // 门窗套保温厚 double TDbOpening::GetSlotInsulateThick() const { if (!DocGetProWinSlabInsu()) { return 0.0; } double dThick = 0.0; int nMat = 0; BOOL bSlotInsCap = TRUE; ReadInsulateFromXData(nMat, dThick, bSlotInsCap); if (nMat == 2 || nMat == 3) {//材质是保温和轻质材料时,没有保温层 return 0.0; } return dThick; } void TDbOpening::SetSlotInsulateThick(double dThick) { double dThickT = 0.0; int nMat = 0; BOOL bSlotInsCap = TRUE; ReadInsulateFromXData(nMat, dThickT, bSlotInsCap); WriteInsulateToXData(nMat,dThick,bSlotInsCap); //wlw add 100913 m_dInsWidth = dThick; } // 门窗套保温是否封口,默认封口 BOOL TDbOpening::HasSlotInsulateCap() const { assertReadEnabled(); double dThickT = 0.0; int nMat = 0; BOOL bSlotInsCap = TRUE; ReadInsulateFromXData(nMat, dThickT, bSlotInsCap); return bSlotInsCap; } void TDbOpening::SetSlotInsulateCap(BOOL bSlotInsCap) { assertWriteEnabled(); double dThick = 0.0; int nMat = 0; BOOL bSlotInsCapT = TRUE; ReadInsulateFromXData(nMat, dThick, bSlotInsCapT); WriteInsulateToXData(nMat,dThick, bSlotInsCap); //wlw add 110118 m_bSlotInsCap = bSlotInsCap; } // 凸窗挡板保温厚与门窗套共用 double TDbOpening::GetProWinSlabInsuThick() const { return GetSlotInsulateThick(); } void TDbOpening::SetProWinSlabInsuThick(double dThick) { SetSlotInsulateThick(dThick); } // 门口线偏移距离(只对单侧、双侧起作用) double TDbOpening::GetDoorLineOffsetDist() const { assertReadEnabled(); const TEntityFields &fd = GetFields(); double dOffsetDist = 0; fd.GFD(_T("门口线偏移距离"), dOffsetDist); return dOffsetDist; } void TDbOpening::SetDoorLineOffsetDist(double dOffsetDist) { assertWriteEnabled(); TEntityFields &fd = Fields(); fd.SFD(_T("门口线偏移距离"), dOffsetDist); } // 门、窗、弧窗的自类型(支持用户设置,无法用枚举类型) CString TDbOpening::GetSubKind() const { assertReadEnabled(); const TEntityFields &fd = GetFields(); CString csSubKind = _T("普通门"); switch (m_opKind) { case TDbOpening::OP_DOOR: // 门 break; case TDbOpening::OP_WINDOW: // 窗 csSubKind = _T("普通窗"); break; case TDbOpening::OP_ARCWIN: // 弧窗 csSubKind = _T("弧窗"); break; default: // 其他类型 csSubKind = GetKindString(); break; } fd.GFD(_T("门窗用途"), csSubKind); return csSubKind; } void TDbOpening::SetSubKind(const TCHAR *csKind) { assertWriteEnabled(); if (GetKind() == TOpeningData::OP_DOOR) // 门 { bool bAddFlag1 = _tcsicmp(csKind, _T("隔断门"))==0, bAddFlag2 = _tcsicmp(csKind, _T("电梯门"))==0; if (bAddFlag1) // 是隔断门 { m_nOpStyle |= OPS_LVTRY; m_nOpStyle &= ~OPS_LIFTDOOR; } else if (bAddFlag2) // 是电梯门 { m_nOpStyle |= OPS_LIFTDOOR; m_nOpStyle &= ~OPS_LVTRY; } else // 都不是 { m_nOpStyle &= ~OPS_LVTRY; m_nOpStyle &= ~OPS_LIFTDOOR; } } TEntityFields &fd = Fields(); fd.SFD(_T("门窗用途"), csKind); } BOOL TDbOpening::HasInsulate() const { return ((m_nOpStyle & OPS_SLOT_INSULATE) != 0); } void TDbOpening::SetInsulate(BOOL bTrue) { if (bTrue) { m_nOpStyle |= OPS_SLOT_INSULATE; } else { m_nOpStyle &= ~OPS_SLOT_INSULATE; } } bool TDbOpening::ReadInsulateFromXData(int& nMaterial, double& dThick, BOOL &bSlotInsCap)const { assertReadEnabled(); nMaterial = 0; dThick = 0.0; bSlotInsCap = TRUE; AcGeVector3d vtTemp; resbuf *pXData = NULL; pXData = this->xData(TDBOPENING_INSULATE); if (pXData != NULL) { resbuf* pRb = pXData; pRb = pRb->rbnext; if (NULL != pRb && pRb->restype == AcDb::kDxfXdInteger32) { nMaterial = pRb->resval.rint; } pRb = pRb->rbnext; if (NULL != pRb && pRb->restype == AcDb::kDxfXdReal) { dThick = pRb->resval.rreal; } pRb = pRb->rbnext; if (NULL != pRb && pRb->restype == AcDb::kDxfXdInteger32) { bSlotInsCap = pRb->resval.rint; } acutRelRb(pXData); return true; } return false; } bool TDbOpening::WriteInsulateToXData(int nMaterial, double dThick, BOOL bSlotInsCap) { assertWriteEnabled(); resbuf *pXData = NULL; TGRegApp(TDBOPENING_INSULATE, database()); pXData = this->xData(TDBOPENING_INSULATE); if (pXData == NULL) { pXData = ads_buildlist(1001, TDBOPENING_INSULATE, NULL); } resbuf* pRbTemp = NULL; resbuf* pRb = NULL; pRbTemp = acutNewRb(AcDb::kDxfXdInteger32); pRbTemp->resval.rint = nMaterial; pXData->rbnext = pRbTemp; pRb = pRbTemp; pRbTemp = acutNewRb(AcDb::kDxfXdReal); pRbTemp->resval.rreal = dThick; pRb->rbnext = pRbTemp; pRb = pRbTemp; pRbTemp = acutNewRb(AcDb::kDxfXdInteger32); pRbTemp->resval.rint = bSlotInsCap; pRb->rbnext = pRbTemp; pRb = pRbTemp; Acad::ErrorStatus es = this->setXData(pXData); acutRelRb(pXData); if (es == Acad::eOk) { return true; } return false; } // sg add 101115,支持统一标高 // 需要特殊说明,此类中的dElevation形参,表示的是门窗所在墙,未来会变成的标高值 bool TDbOpening::UnifyElevation(double dElevation) { assertWriteEnabled(); // 获得当前门槛高、窗台高 double dSill = GetSill(); // 仿照SetSill函数的实现,在门槛高、窗台高不变的情况下,修改门窗的绝对标高 m_ptLocation.z = dElevation + dSill; return true; } void Matrix3D2String( const AcGeMatrix3d &mat, CString &str ) { #if ADS <= 15 std::ostringstream stream; #else std::wostringstream stream; #endif for (int ln = 0; ln < 4; ++ln) { for (int col = 0; col < 4; ++col) { stream << mat.entry[ln][col]; #if ADS <= 15 stream << " "; #else stream << L" "; #endif } } str = stream.str().c_str(); } //add by xlc on 101112 CString TDbOpening::GetXml(const AcGeMatrix3d& mat) const { TXmlTree xmlTree; POSITION posRoot = xmlTree.Insert(_T("ATS_OPENING"), NULL, NULL); { xmlTree.SetAttribute(posRoot, _T("name"), _T("门窗")); xmlTree.SetAttribute(posRoot, _T("comment"), _T("上华对象名称")); } CString strText; 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 posItem = NULL; POSITION posItem2 = xmlTree.Insert(_T("Link_WALL"), posRoot, posItem1); { xmlTree.SetAttribute(posItem2, _T("name"), _T("连接墙体")); posItem = xmlTree.Insert(_T("Link_ID"), posItem2, NULL); { xmlTree.SetAttribute(posItem, _T("name"), _T("墙体句柄")); strText.Format(_T("%ld"), m_nIdOfWall); xmlTree.SetItemText(posItem, strText); } } POSITION posItem3 = xmlTree.Insert(_T("Property"), posRoot, posItem2); { xmlTree.SetAttribute(posItem3, _T("name"), _T("门窗类型")); xmlTree.SetAttribute(posItem3, _T("comment"), _T("门窗的类型")); xmlTree.SetItemText(posItem3, GetKindString()); } // double m_nProtrude; //突出宽 // double m_nTrapezia; //梯形宽 if (GetKind()==OP_PROWIN && m_pBayWin!=NULL) { POSITION posType = xmlTree.Insert(_T("PrType"), posRoot, posItem3); { xmlTree.SetAttribute(posType, _T("name"), _T("凸窗类型")); strText.Format(_T("%d"), m_pBayWin->m_nStyle); xmlTree.SetItemText(posType,strText); } POSITION posStrude = xmlTree.Insert(_T("ProTrude"), posRoot, posType); { xmlTree.SetAttribute(posStrude, _T("name"), _T("出挑长")); strText.Format(_T("%f"), m_pBayWin->m_nProtrude); xmlTree.SetItemText(posStrude,strText); } POSITION posZia = xmlTree.Insert(_T("B"), posRoot, posStrude); { xmlTree.SetAttribute(posZia, _T("name"), _T("梯形宽")); strText.Format(_T("%f"), m_pBayWin->m_nTrapezia); xmlTree.SetItemText(posZia,strText); } posItem3 = posZia; } POSITION posItem4 = xmlTree.Insert(_T("Height"), posRoot, posItem3); { xmlTree.SetAttribute(posItem4, _T("name"), _T("门窗高")); xmlTree.SetAttribute(posItem4, _T("comment"), _T("从门窗底起算的窗高")); strText.Format(_T("%f"), GetHeight()); xmlTree.SetItemText(posItem4, strText); } POSITION posItem5 = xmlTree.Insert(_T("Length"), posRoot, posItem4); { xmlTree.SetAttribute(posItem5, _T("name"), _T("门窗宽")); xmlTree.SetAttribute(posItem5, _T("comment"), _T("门窗沿墙面的宽度")); strText.Format(_T("%f"), GetWidth()); xmlTree.SetItemText(posItem5, strText); } POSITION posItem51 = xmlTree.Insert(_T("LengthTwoDoor"), posRoot, posItem5); { xmlTree.SetAttribute(posItem51, _T("name"), _T("主门宽")); xmlTree.SetAttribute(posItem51, _T("comment"), _T("门连窗、子母门")); strText.Format(_T("%f"), m_nDoorWidth); xmlTree.SetItemText(posItem51, strText); } POSITION posItem52 = xmlTree.Insert(_T("LengthDoorWinH"), posRoot, posItem51); { xmlTree.SetAttribute(posItem52, _T("name"), _T("窗高")); xmlTree.SetAttribute(posItem52, _T("comment"), _T("门连窗")); strText.Format(_T("%f"), m_nWinHeight); xmlTree.SetItemText(posItem52, strText); } POSITION posItem6 = xmlTree.Insert(_T("Thickness"), posRoot, posItem5); { xmlTree.SetAttribute(posItem6, _T("name"), _T("窗厚")); xmlTree.SetAttribute(posItem6, _T("comment"), _T("窗厚与推拉门厚随墙")); strText.Format(_T("%f"), GetWallThickness()); xmlTree.SetItemText(posItem6, strText); } POSITION posItem7 = xmlTree.Insert(_T("Ang"), posRoot, posItem6); { xmlTree.SetAttribute(posItem7, _T("name"), _T("圆心角")); strText = _T("0"); if (GetKind() == TOpeningData::OP_ARCWIN) { TAcDbObjectPtr objWall(m_nIdOfWall, AcDb::kForRead); if(!!objWall) { TDbWall *pDbWall = TDbWall::cast(objWall.m_pObject); if(pDbWall) { TGGeArc ar = pDbWall->GetArc(); double dRadius = ar.GetRadius(); if(dRadius > _DIST_SNAP) { double dAng = GetWidth() / dRadius; strText.Format(_T("%f"), dAng); } } } } xmlTree.SetItemText(posItem7, strText); } // 旋转角度 POSITION posRotate = xmlTree.Insert(_T("RoataeAngle"), posRoot, posItem7); { xmlTree.SetAttribute(posRotate, _T("name"), _T("旋转角度")); strText.Format(_T("%f"), m_nRotation); xmlTree.SetItemText(posRotate, strText); posItem7 = posRotate; } POSITION posItem8 = xmlTree.Insert(_T("Open_ang"), posRoot, posItem7); { xmlTree.SetAttribute(posItem8, _T("name"), _T("开启方向")); strText.Format(_T("%d"), m_nQuadrant); xmlTree.SetItemText(posItem8, strText); } POSITION posItem9 = xmlTree.Insert(_T("Highwin_ID"), posRoot, posItem8); { xmlTree.SetAttribute(posItem9, _T("name"), _T("高窗标志")); xmlTree.SetAttribute(posItem9, _T("comment"), _T("高窗为1")); strText.Format(_T("%d"), IsHigh()); xmlTree.SetItemText(posItem9, strText); } POSITION posItem10 = xmlTree.Insert(_T("Upperwin_ID"), posRoot, posItem9); { xmlTree.SetAttribute(posItem10, _T("name"), _T("上层窗标志")); xmlTree.SetAttribute(posItem10, _T("comment"), _T("上层窗为1")); strText.Format(_T("%d"), IsHighLevel()); xmlTree.SetItemText(posItem10, strText); } POSITION posItem11 = xmlTree.Insert(_T("Center_point"), posRoot, posItem10); { // sg modify 120117,对点进行坐标变换 TADSGePoint3d ptTransformBy = GetLocation(); ptTransformBy.TransformBy(mat); xmlTree.SetAttribute(posItem11, _T("name"), _T("基点")); xmlTree.SetAttribute(posItem11, _T("comment"), _T("窗台中点坐标")); // strText.Format(_T("%f,%f,%f"), GetLocation().x, GetLocation().y, GetLocation().z); strText.Format(_T("%f,%f,%f"), ptTransformBy.x, ptTransformBy.y, ptTransformBy.z); xmlTree.SetItemText(posItem11, strText); } POSITION posItem12 = xmlTree.Insert(_T("Lib_Block"), posRoot, posItem11); { xmlTree.SetAttribute(posItem12, _T("name"), _T("图块符号表")); posItem = NULL; posItem = xmlTree.Insert(_T("Lib_2D"), posItem12, posItem); { xmlTree.SetAttribute(posItem, _T("name"), _T("二维门窗块名")); TCString sName; GetStyle2dName(sName); xmlTree.SetItemText(posItem, sName); } posItem = xmlTree.Insert(_T("Lib_3D"), posItem12, posItem); { xmlTree.SetAttribute(posItem, _T("name"), _T("三维门窗块名")); TCString sName; GetStyle3dName(sName); xmlTree.SetItemText(posItem, sName); } } POSITION pos = posItem12; AcDbObjectId idStyle = !m_nIdStyle3d ? m_nIdStyle2d : m_nIdStyle3d; if(idStyle != NULL) { POSITION posItem13 = xmlTree.Insert(_T("Matrix3d"), posRoot, posItem12); { double dScaleX(0), dScaleY(0), dScaleZ(0), dRotation(m_nRotation); GetInsert3DScale(&dScaleX, &dScaleY, &dScaleZ); AcDbBlockReference block(GetLocation(), idStyle); block.setRotation(dRotation); if (!(!m_nIdStyle3d)) // 显示真三维 block.setScaleFactors(AcGeScale3d(dScaleX, dScaleY, dScaleZ)); else if (!!m_nIdStyle2d) block.setScaleFactors(AcGeScale3d(dScaleX, dScaleY, m_nHeight)); AcGeMatrix3d matBlock = block.blockTransform(); matBlock = mat * matBlock; CString sMat; Matrix3D2String(matBlock, sMat); xmlTree.SetAttribute(posItem13, _T("name"), _T("矩阵")); xmlTree.SetAttribute(posItem13, _T("comment"), _T("图块转换矩阵")); xmlTree.SetItemText(posItem13, sMat); } pos = posItem13; } if (IsShowLabel()) { POSITION posLabel = xmlTree.Insert(_T("Label"), posRoot, pos); xmlTree.SetAttribute(posLabel, _T("name"), _T("门窗编号")); xmlTree.SetItemText(posLabel, m_sLabel); pos = posLabel; } // add by hh 2013-9-6 从xData中读取节能相关的数据 if(11 == g_nProductId) { acdbRegApp(_T("TBEC_XDAPP_OPENING")); resbuf* xdata = xData(_T("TBEC_XDAPP_OPENING")); if(NULL != xdata) { static struct _XDataList{ int nCode; // CODE LPCTSTR pszItem; // 节点 LPCTSTR pszName; // 节点名称 } xDList1[] = { // 门 { AcDb::kDxfXdAsciiString, _T("Struct_name"), _T("构造名称") }, { AcDb::kDxfXdReal, _T("Struct_K"), _T("传热系数") }, }, xDList2[] = { // 外窗 { AcDb::kDxfXdAsciiString, _T("Struct_name"), _T("构造名称") }, { AcDb::kDxfXdReal, _T("Struct_K"), _T("传热系数") }, { AcDb::kDxfXdReal, _T("Struct_SC"), _T("遮阳系数") }, { AcDb::kDxfXdAsciiString, _T("SD_name"), _T("外遮阳类型") }, { AcDb::kDxfXdReal, _T("Struct_SDs"), _T("夏季外遮阳系数") }, { AcDb::kDxfXdReal, _T("Struct_SDw"), _T("冬季外遮阳系数") }, }, xDList3[] = { // 内窗 { AcDb::kDxfXdAsciiString, _T("Struct_name"), _T("构造名称") }, { AcDb::kDxfXdReal, _T("Struct_K"), _T("传热系数") }, { AcDb::kDxfXdReal, _T("Struct_SC"), _T("遮阳系数") }, }, xDList4[] = { // 外凸窗 { AcDb::kDxfXdAsciiString, _T("Struct_name"), _T("构造名称") }, { AcDb::kDxfXdReal, _T("Struct_K"), _T("传热系数") }, { AcDb::kDxfXdReal, _T("Struct_SC"), _T("遮阳系数") }, { AcDb::kDxfXdAsciiString, _T("SD_name"), _T("外遮阳类型") }, { AcDb::kDxfXdReal, _T("Struct_SDs"), _T("夏季外遮阳系数") }, { AcDb::kDxfXdReal, _T("Struct_SDw"), _T("冬季外遮阳系数") }, { AcDb::kDxfXdAsciiString, _T("TopSlab_name"), _T("顶板构造名称") }, { AcDb::kDxfXdReal, _T("TopSlab_K"), _T("顶板传热系数") }, { AcDb::kDxfXdReal, _T("TopSlab_D"), _T("顶板热惰性指标") }, { AcDb::kDxfXdReal, _T("TopSlab_R"), _T("顶板热阻") }, { AcDb::kDxfXdAsciiString, _T("BottomSlab_name"), _T("底板构造名称") }, { AcDb::kDxfXdReal, _T("BottomSlab_K"), _T("底板传热系数") }, { AcDb::kDxfXdReal, _T("BottomSlab_D"), _T("底板热惰性指标") }, { AcDb::kDxfXdReal, _T("BottomSlab_R"), _T("底板热阻") }, { AcDb::kDxfXdAsciiString, _T("SideSlab_name"), _T("侧板构造名称") }, { AcDb::kDxfXdReal, _T("SideSlab_K"), _T("侧板传热系数") }, { AcDb::kDxfXdReal, _T("SideSlab_D"), _T("侧板热惰性指标") }, { AcDb::kDxfXdReal, _T("SideSlab_R"), _T("侧板热阻") }, }, xDListShadow[] = { // 外遮阳绘制参数 { AcDb::kDxfXdInteger32, _T("SD_mask%d"), _T("外遮阳") }, { AcDb::kDxfXdReal, _T("SD_para%d"), _T("参数A") }, { AcDb::kDxfXdReal, _T("SD_parb%d"), _T("参数B") }, { AcDb::kDxfXdReal, _T("SD_parc%d"), _T("参数C") }, }; // 取得门窗标记 resbuf* px = xdata; px = px->rbnext; int nOpening = 1; // 1 门 2 窗 3 凸窗 if(NULL != px && AcDb::kDxfXdInteger32 == px->restype) { nOpening = px->resval.rint; } int nOut = 0; // 0 内窗; 1 外窗; 2 带外遮阳的外窗 if(1 != nOpening) // 如果是窗户或者凸窗 再读取一下内外窗标记 { px = px->rbnext; if(NULL != px && AcDb::kDxfXdInteger32 == px->restype) { nOut = px->resval.rint; } } // 根据门窗标记 选择数据 _XDataList* xDList = NULL; int nSize = 0; if(1 == nOpening) // 门 { xDList = xDList1; nSize = sizeof(xDList1) / sizeof(xDList1[0]); } else // 窗 凸窗 { if(0 == nOut) // 内窗 { xDList = xDList3; nSize = sizeof(xDList3) / sizeof(xDList3[0]); } else { if(3 == nOpening) // 外凸窗 { xDList = xDList4; nSize = sizeof(xDList4) / sizeof(xDList4[0]); } else // 普通外窗 { xDList = xDList2; nSize = sizeof(xDList2) / sizeof(xDList2[0]); } } } // 根节点 POSITION posBec = xmlTree.Insert(_T("TBecParam"), posRoot, pos); xmlTree.SetAttribute(posBec, _T("name"), _T("节能参数")); // 节能数据 CString sTemp; posItem = NULL; for(int i = 0; i < nSize && NULL != px; i++) { px = px->rbnext; if(NULL != px && xDList[i].nCode == px->restype) { if(AcDb::kDxfXdAsciiString == xDList[i].nCode) sTemp = px->resval.rstring; else if(AcDb::kDxfXdReal == xDList[i].nCode) sTemp.Format(_T("%.2f"), px->resval.rreal); posItem = xmlTree.Insert(xDList[i].pszItem, posBec, posItem); xmlTree.SetAttribute(posItem, _T("name"), xDList[i].pszName); xmlTree.SetItemText(posItem, sTemp); } } // 外遮阳绘制参数 if(NULL != px && 2 == nOut) { CString sItem; px = px->rbnext; if(NULL != px && AcDb::kDxfXdInteger32 == px->restype) { int nLoop = ((1 == px->resval.rint) ? 2 : 1); // 单一遮阳/组合遮阳 nSize = sizeof(xDListShadow) / sizeof(xDListShadow[0]); for(int k = 0; k < nLoop; k++) { for(int j = 0; j < nSize && NULL != px; j++) { px = px->rbnext; if(NULL != px && xDListShadow[j].nCode == px->restype) { if(AcDb::kDxfXdInteger32 == xDListShadow[j].nCode) sTemp.Format(_T("%d"), px->resval.rint); else if(AcDb::kDxfXdReal == xDListShadow[j].nCode) sTemp.Format(_T("%.2f"), px->resval.rreal); sItem.Format(xDListShadow[j].pszItem, k + 1); posItem = xmlTree.Insert(sItem, posBec, posItem); xmlTree.SetAttribute(posItem, _T("name"), xDListShadow[j].pszName); xmlTree.SetItemText(posItem, sTemp); } } } } } acutRelRb(xdata); pos = posBec; } } CString strBase = TEntityBase::GetXml(mat); CString strXml = xmlTree.GetXml(); int nIndex = strXml.Find(_T(" §ionRecords, AcDbVoidPtrArray& arFillPtrs ) const { TGGeSectionPlane section(face, vtPlaneSecDir); // 构造投影面 OpeningKind kind = GetKind(); AcDbObjectId id = objectId(); AcDbObjectId layer = layerId(); double elev = GetElevation(); double height = GetHeight(); TGGePoly2D poly_elev, poly_xy; // 立面曲线,x-y面曲线 TObjSectionRecord::SectionType type = TObjSectionRecord::eTCH_OPENING; GetElevOutline(poly_elev); GetOutlinePoly(0., poly_xy); switch (kind) { case OP_DOOR: case OP_WINDOW: case OP_HOLE: case OP_TWODOOR: case OP_GROUP: case OP_ARCWIN: { SectionUtility::FillRecordsByPoly(poly_xy, section, sectionRecords, elev, height, *this, type); } break; case OP_DOORWIN: { // 利用 立面曲线 左右拉伸得到两个立面 AcGeMatrix3d mat; TGGePoly2D poly; TGGePoly2D poly1(poly_elev), poly2(poly_elev); TADSGePoint3d ptB, ptF; GetSidePoints(ptB, ptF); AcGeVector3d vt = ptB - ptF; vt.normalize(); vt *= GetWallThickness() * .5; vt.rotateBy(PI * -.5, AcGeVector3d::kZAxis); mat.setTranslation(vt); poly1.TransformBy(mat); vt.rotateBy(PI, AcGeVector3d::kZAxis); mat.setTranslation(vt); poly2.TransformBy(mat); TGGeSectionPlane plane1(poly1, AcGeVector3d::kZAxis), plane2(poly2, AcGeVector3d::kZAxis); // 两个立面进行投影 poly.Reset(); double dDis = SectionUtility::Projection_plane2plane(section, plane1, poly); if (poly.Length()) sectionRecords.push_back(TObjSectionRecord(id, layer, type, dDis, poly)); poly.Reset(); dDis = SectionUtility::Projection_plane2plane(section, plane2, poly); if (poly.Length()) sectionRecords.push_back(TObjSectionRecord(id, layer, type, dDis, poly)); } break; // case OP_ARCWIN: // { // SectionUtility::DrawPoly2D(poly_elev); // SectionUtility::DrawPoly2D(poly_xy); // } // break; case OP_PROWIN: { double nWallThick = 200.; double dWallInsut = 0., dInsutAdd = 0.; TADSGePoint3d ptDir; double nExtDir = m_nRotation + (m_nQuadrant<2? PI/2.0 : -PI/2.0); TADSGePoint3d ptLoc = GetLocation(); ptLoc.z = 0; // sg modify 120605,标记保温类型 int nInsulateType = 0; OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall); if(pWall) { nWallThick = pWall->GetWidth(4); ads_polar(ptLoc, nExtDir, 10000, ptDir); int nSide = pWall->OnWhichSide(ptDir); if (pWall->IsInsulateOnSide(nSide)) { dWallInsut = pWall->GetInsulateThick(nSide); if (DocGetProWinSlabInsu()) { dInsutAdd = GetSlotInsulateThick(); nInsulateType = 1; } } ads_polar(ptLoc, nExtDir, -10000, ptDir); if (pWall->IsInsulateOnSide(pWall->OnWhichSide(ptDir))) { dInsutAdd = GetSlotInsulateThick(); nInsulateType = (nInsulateType==1) ? 2 : 1; } } OPENOBJ_END(); DList polyCurves; //m_pBayWin->GetPolyCurve(ptLoc, nExtDir, GetWidth(), nWallThick, HasLeftSlab(), HasRightSlab(), polyCurves, dWallInsut, dInsutAdd); m_pBayWin->GetPolyCurve(ptLoc, nExtDir, GetWidth(), nWallThick, HasLeftSlab(), HasRightSlab(), polyCurves, dWallInsut, dInsutAdd, nInsulateType==2); if (m_pBayWin->m_nStyle != 3) { SectionUtility::FillRecordsByPoly(*polyCurves[polyCurves.Length()-1], section, sectionRecords, elev, height, *this, type); } else// 拱形 { TGGePoly2D poly = *polyCurves[polyCurves.Length() - 1]; if (poly.Length() == 2) { double dAng = poly.GetBulge(0) * .5; AcGePoint3d pt1(*poly[0]), pt2(*poly[1]); double dLen = pt1.distanceTo(pt2) * .5; AcGeVector3d vt = pt1 - pt2; vt.normalize(); vt *= (dLen/sin(dAng) - dLen/tan(dAng)); vt.rotateBy(PI*.5, AcGeVector3d::kZAxis); AcGePoint3d pt3 = pt2 + vt; AcGePoint3d pt4 = pt1 + vt; TGGePoly2D _poly; _poly.AppendNode(pt1); _poly.AppendNode(pt2); _poly.AppendNode(pt3); _poly.AppendNode(pt4); _poly.SetClosed(); SectionUtility::FillRecordsByPoly(_poly, section, sectionRecords, elev, height, *this, type); } } } break; case OP_CORNWIN: break; default: break; } // 处理添充线 switch (kind) { case OP_DOOR: break; case OP_WINDOW: break; case OP_DOORWIN: break; case OP_TWODOOR: break; default: break; } return true; }