#include "stdafx.h" #include "AecDbOpening.h" #include "AecDbWall.h" #include "MFCDbDwgFiler.h" #include "KTCADUtilityEx.h" #include "dbgrip.h" #include "AecGripCback.h" #include "KTSetting.h" #include "geometry2json.h" #include "AcGiViewDraw.h" #include "AcDbX3dSolid.h" #include "CoreTools.h" #include "ImpMD5.h" #include "simpleProperty.h" extern AcGePoint3d MidPoint(const AcGePoint3d& pt1,const AcGePoint3d& pt2); extern void transfromRegion(AcDbRegion *pRegion, const AcGePoint3d &ptOnRegion, const AcGeVector3d &vtNormal, const AcGePoint3d &ptOnPlan); extern void PushGripMessage(GripMessage&); extern BOOL GetDocScale(double& dPScale); extern void DLLIMPEXP OrthoProjectedEntity(AcDbEntity *pEnt, const AcGePlane &plan, AcGeMatrix3d &xformPlanToWorld, AcDbVoidPtrArray &arEntPtrs); extern DLLIMPEXP bool MakeBlockRefSet(AcDbVoidPtrArray &arEntPtrs, const AcDbObjectId &idLay,Adesk::Boolean bDoSubent, LPCTSTR pszName, AcDbDatabase *pDb = NULL); extern Acad::ErrorStatus AddToModelSpace(AcDbEntity *pEnt, AcDbDatabase *pDb = NULL, bool bClose = true); ACRX_DXF_DEFINE_MEMBERS(AecDbXOpening, AecDbEntityBase, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, AcDbProxyEntity::kNoOperation | AcDbProxyEntity::kDisableProxyWarning, AEC_DBOPENING, "AecDbXOpening" "|Product Desc: shanghua earthworm app obj" "|Company: shanghua inc" "|WEB Address: www.shanghuasoft.com") Adesk::UInt32 AecDbXOpening::kCurrentVersionNumber = 1; static const Adesk::UInt16 kColorByBlock = 0; static const Adesk::UInt16 kRed = 1; static const Adesk::UInt16 kYellow = 2; static const Adesk::UInt16 kGreen = 3; static const Adesk::UInt16 kCyan = 4; static const Adesk::UInt16 kBlue = 5; static const Adesk::UInt16 kMagenta = 6; static const Adesk::UInt16 kWhite = 7; static const Adesk::UInt16 kColorByLayer = 256; static void FreeBuffer(int n,AcDbVoidPtrArray& arEntPtrs) { AcDbEntity* pEnt = NULL; while(arEntPtrs.length() > n ) { pEnt = (AcDbEntity*)arEntPtrs.last(); if (pEnt != NULL) { pEnt->erase(); pEnt->close(); arEntPtrs.removeLast(); DELETE_PTR(pEnt); } } } extern CString IDCreate(); AecDbXOpening::AecDbXOpening(void) { m_pGripAppData = new AecGripData[10]; m_mapSpecXData.SetAt(KEY_NAME,_T("门窗")); m_mapSpecXData.SetAt(KEY_NO, IDCreate()); } AecDbXOpening::~AecDbXOpening(void) { delete [] m_pGripAppData; } /* typedef struct OpeningData { int nType; //窗:0 门 1 int nFlag; //特殊标记 double dWidth; //门窗宽度 double dHeight; //门窗高度 double dBomEl; //相对墙体底部标高 AcGePoint3d ptPos; //位置,Z是真实标高 TCHAR szBlockName2d[MAX_PATH];//本地文件名2d TCHAR szBlockName3d[MAX_PATH];//本地文件名3d TCHAR szName[MAX_PATH]; //名称 TCHAR szSpec[MAX_PATH]; //附属信息 TCHAR szNo[65];//编号 TCHAR szFactory[MAX_PATH];//厂家 }OPENINGDATA; */ extern void GetMidPoint(AcDbCurve* pNaCurve,AcGePoint3d& ptMid); void AecDbXOpening::SetOpeningData( const OpeningData& data,const AcDbObjectId& idWall) { AssertWriteEnabled(); m_mapSpecXData.SetAt(KEY_TYPE,data.nType); m_mapSpecXData.SetAt(KEY_FLAG,data.nFlag); m_mapSpecXData.SetAt(KEY_Width,data.dWidth); m_mapSpecXData.SetAt(KEY_HEIGHT,data.dHeight); m_mapSpecXData.SetAt(KEY_ORGPT,data.ptPos); m_mapSpecXData.SetAt(KEY_NAME,data.szName); m_mapSpecXData.SetAt(KEY_BLK2D,data.szBlockName2d); m_mapSpecXData.SetAt(KEY_BLK3D,data.szBlockName3d); m_mapSpecXData.SetAt(PIPE_SPEC,data.szSpec); m_mapSpecXData.SetAt(KEY_BOMEL,data.dBomEl); m_mapSpecXData.SetAt(KEY_IDCNT1,idWall); m_mapSpecXData.SetAt(KEY_LabelText,data.szNo); m_mapSpecXData.SetAt(KEY_FACTORY, data.szFactory); m_mapSpecXData.SetAt(KEY_ADDBAF1,data.bAddBaf1); m_mapSpecXData.SetAt(KEY_ADDBAF2,data.bAddBaf2); AcDbEntity* pEnt = NULL; if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,idWall,AcDb::kForRead)) { AecDbXWall* pWall = AecDbXWall::cast(pEnt); if (pWall != NULL) { AcGePoint3d ptOn; AcGeVector3d vtDir; BOOL bIsVView = FALSE; pWall->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_VVIEW,bIsVView); if (bIsVView) { //1.创建整体Solid AcGePoint3d ptOnRegion; pWall->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_SECCEN,ptOnRegion); AcDbCurve* pNaCur = pWall->GetNativeCurve(); AcGePoint3d ptSta,ptEnd; pNaCur->getStartPoint(ptSta); pNaCur->getEndPoint(ptEnd); AcGeVector3d vtNormal(AcGeVector3d::kIdentity); pNaCur->getFirstDeriv(ptSta, vtNormal); AcDbRegion* pCloneRegion = pWall->GetSection(); transfromRegion(pCloneRegion, ptOnRegion, vtNormal, ptEnd); AcDbLine* pLn1 = AecDbXWall::GetOrthoProjectOnXY(pCloneRegion); if (pLn1 != NULL) { AcGePoint3d ptMid,ptMid2; GetMidPoint(pNaCur,ptMid); ptMid.z = 0.0; pLn1->getClosestPointTo(ptMid,ptMid2); AcGeVector3d vtM = ptMid - ptMid2; AcGeMatrix3d xM;xM.setToTranslation(vtM); pLn1->transformBy(vtM); pLn1->getClosestPointTo(data.ptPos,ptOn); pLn1->getFirstDeriv(ptOn,vtDir); delete pLn1; } delete pCloneRegion; } else { pWall->getClosestPointTo(data.ptPos,ptOn); pWall->getFirstDeriv(ptOn,vtDir); } vtDir.normalize(); ptOn.z = 0.0;//以XY面为准 WallData wData; pWall->GetWallData(wData); ptOn.z += wData.dBomEl;//真实标高 //记录墙体的走向和宽度 m_mapSpecXData.SetAt(PIPE_DIR,vtDir); m_mapSpecXData.SetAt(PIPE_TDIR,1); m_mapSpecXData.SetAt(KEY_PTON,ptOn); m_mapSpecXData.SetAt(KEY_THICK,wData.dThick); vtDir.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); vtDir.normalize(); vtDir *= 3.5 * 100.0; ptOn += vtDir; m_mapSpecXData.SetAt(KEY_NOPOS,ptOn); } pEnt->close(); } //加载block2d AcDbObjectId idBlk2d; idBlk2d = KTCADUtilityEx::InsertBlock(data.szBlockName2d); m_mapSpecXData.SetAt(KEY_BLK2DID,idBlk2d,FALSE); AcDbObjectId idBlk3d; idBlk3d = KTCADUtilityEx::InsertBlock(data.szBlockName3d); m_mapSpecXData.SetAt(KEY_BLK3DID,idBlk3d,FALSE); } void AecDbXOpening::UpdateOpeningData(const OpeningData& data) { AssertWriteEnabled(); PreRefreshWallDraw(); //TEST //TCHAR szH[17]; //objectId().handle().getIntoAsciiBuffer(szH); //acutPrintf(_T("\n%s"), szH); m_mapSpecXData.SetAt(KEY_TYPE,data.nType); m_mapSpecXData.SetAt(KEY_FLAG,data.nFlag); m_mapSpecXData.SetAt(KEY_Width,data.dWidth); m_mapSpecXData.SetAt(KEY_HEIGHT,data.dHeight); m_mapSpecXData.SetAt(KEY_THICK, data.dThick); m_mapSpecXData.SetAt(KEY_NAME,data.szName); m_mapSpecXData.SetAt(KEY_BLK2D,data.szBlockName2d); m_mapSpecXData.SetAt(KEY_BLK3D,data.szBlockName3d); m_mapSpecXData.SetAt(PIPE_SPEC,data.szSpec); AcDbObjectId idWall; m_mapSpecXData.GetAt(KEY_IDCNT1,idWall); double dBomEl = data.dBomEl; AcDbEntity* pEnt = NULL; if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,idWall,AcDb::kForRead) ) { AecDbXWall* pWall = AecDbXWall::cast(pEnt); if (pWall != NULL) { WallData wdata; pWall->GetWallData(wdata); dBomEl += wdata.dBomEl; } pEnt->close(); } m_mapSpecXData.SetAt(KEY_BOMEL,dBomEl); //m_mapSpecXData.SetAt(KEY_NO,data.szNo); m_mapSpecXData.SetAt(KEY_LabelText,data.szNo); m_mapSpecXData.SetAt(KEY_FACTORY,data.szFactory); //加载block2d AcDbObjectId idBlk2d; idBlk2d = KTCADUtilityEx::InsertBlock(data.szBlockName2d); m_mapSpecXData.SetAt(KEY_BLK2DID,idBlk2d,FALSE); AcDbObjectId idBlk3d; idBlk3d = KTCADUtilityEx::InsertBlock(data.szBlockName3d); m_mapSpecXData.SetAt(KEY_BLK3DID,idBlk3d,FALSE); RefreshWallDraw(); } Acad::ErrorStatus AecDbXOpening::SetLabel(const TCHAR* pszLab) { assertWriteEnabled(); if (pszLab != NULL) { m_mapSpecXData.SetAt(KEY_LabelText,pszLab); } return Acad::eOk; } CString AecDbXOpening::GetLabel() const { assertReadEnabled(); CString sLab; m_mapSpecXData.GetAt(KEY_LabelText,sLab); return sLab; } void AecDbXOpening::RefreshWallData() { assertWriteEnabled(); AcDbObjectId idWall; m_mapSpecXData.GetAt(KEY_IDCNT1,idWall); AcGePoint3d ptPos; m_mapSpecXData.GetAt(KEY_ORGPT,ptPos); AcDbEntity* pEnt = NULL; if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,idWall,AcDb::kForRead)) { AecDbXWall* pWall = AecDbXWall::cast(pEnt); if (pWall != NULL) { AcGePoint3d ptOn; AcGeVector3d vtDir; pWall->getClosestPointTo(ptPos,ptOn); pWall->getFirstDeriv(ptOn,vtDir); vtDir.normalize(); WallData wData; pWall->GetWallData(wData); //记录墙体的走向和宽度 m_mapSpecXData.SetAt(PIPE_DIR,vtDir); m_mapSpecXData.SetAt(KEY_PTON,ptOn); m_mapSpecXData.SetAt(KEY_THICK,wData.dThick); } pEnt->close(); } } bool AecDbXOpening::GetOpeningData(OpeningData& data) const { assertReadEnabled(); m_mapSpecXData.GetAt(KEY_TYPE,data.nType); m_mapSpecXData.GetAt(KEY_FLAG,data.nFlag); m_mapSpecXData.GetAt(KEY_Width,data.dWidth); m_mapSpecXData.GetAt(KEY_HEIGHT,data.dHeight); m_mapSpecXData.GetAt(KEY_THICK,data.dThick); m_mapSpecXData.GetAt(KEY_ORGPT,data.ptPos); m_mapSpecXData.GetAt(KEY_BOMEL,data.dBomEl); //m_mapSpecXData.GetAt(KEY_NO, data.szNo);//内部使用 m_mapSpecXData.GetAt(KEY_LabelText, data.szNo); if (_tcslen(data.szNo) == 0) m_mapSpecXData.GetAt(KEY_NO, data.szNo); AcDbObjectId idWall; m_mapSpecXData.GetAt(KEY_IDCNT1,idWall); data.idWall = idWall.asOldId(); data.dParamInWall = 0.0; AcGePoint3d ptOn; AcDbEntity* pEnt = NULL; if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,idWall,AcDb::kForRead) ) { AecDbXWall* pWall = AecDbXWall::cast(pEnt); if (pWall != NULL) { WallData wdata; pWall->GetWallData(wdata); //转为相对标高 data.dBomEl -= wdata.dBomEl; pWall->getClosestPointTo(data.ptPos,ptOn); pWall->getParamAtPoint(ptOn,data.dParamInWall); } pEnt->close(); } CString sTmp; m_mapSpecXData.GetAt(KEY_NAME,sTmp); _tcscpy(data.szName,(LPCTSTR)sTmp); m_mapSpecXData.GetAt(KEY_BLK2D,sTmp); _tcscpy(data.szBlockName2d,(LPCTSTR)sTmp); m_mapSpecXData.GetAt(KEY_BLK3D,sTmp); _tcscpy(data.szBlockName3d,(LPCTSTR)sTmp); m_mapSpecXData.GetAt(PIPE_SPEC,sTmp); _tcscpy(data.szSpec,(LPCTSTR)sTmp); m_mapSpecXData.GetAt(KEY_FACTORY, sTmp); _tcscpy(data.szFactory, (LPCTSTR)sTmp); CString sKey; memset(data.dXData,0,sizeof(double) * 16); for(int i = 0;i < 16;i++) { sKey.Format(_T("%s_%d"),KEY_N,i+1); m_mapSpecXData.GetAt(sKey,data.dXData[i]); } m_mapSpecXData.GetAt(KEY_BAYWIN,data.bBayWin); m_mapSpecXData.GetAt(KEY_FTG,data.bFTG); m_mapSpecXData.GetAt(KEY_ADDBAF1,data.bAddBaf1); m_mapSpecXData.GetAt(KEY_ADDBAF2,data.bAddBaf2); return true; } bool AecDbXOpening::GetForHouseSubtract(AcDbVoidPtrArray& arSolidPtrs) const { assertReadEnabled(); OpeningData data; GetOpeningData(data); AcGeVector3d vtDir; m_mapSpecXData.GetAt(PIPE_DIR,vtDir); double dThick = 0.0; m_mapSpecXData.GetAt(KEY_THICK,dThick); AcGePoint3d ptOn; m_mapSpecXData.GetAt(KEY_PTON,ptOn); double dBomEl = 0.0; m_mapSpecXData.GetAt(KEY_BOMEL,dBomEl); ptOn.z = dBomEl;//以门窗保存的标高为准!!! vtDir.normalize(); AcDb3dSolid* pSolid = new AcDb3dSolid; pSolid->createBox(data.dWidth,dThick,data.dHeight); double dAngle = AcGeVector3d::kXAxis.angleTo(vtDir,AcGeVector3d::kZAxis); AcGeMatrix3d xformR; xformR.setToRotation(dAngle,AcGeVector3d::kZAxis); pSolid->transformBy(xformR); AcGeMatrix3d xform; ptOn.z += 0.5 * data.dHeight; xform.setToTranslation(ptOn.asVector()); pSolid->transformBy(xform); arSolidPtrs.append(pSolid); return arSolidPtrs.isEmpty(); } void AecDbXOpening::subList() const { acutPrintf(_T("\n门窗")); AecDbEntityBase::subList(); m_mapSpecXData.List(); } bool AecDbXOpening::GetBimInfoTip(CString& sInfoTip) const { assertReadEnabled(); OpeningData data; memset(&data,0,sizeof(OpeningData)); GetOpeningData(data); CString sField,sFmt; if (data.nType == 1)//门 { sField = _T("门:\n"); sInfoTip += sField; MAKEFIELD(_T("宽度"),_T("%.1f"),data.dWidth,sInfoTip); MAKEFIELD(_T("高度"),_T("%.1f"),data.dHeight,sInfoTip); MAKEFIELD(_T("相对墙底标高"),_T("%.1f"),data.dBomEl,sInfoTip); MAKEFIELD(_T("二维块名"),_T("%s"),data.szBlockName2d,sInfoTip); MAKEFIELD(_T("三维块名"),_T("%s"),data.szBlockName3d,sInfoTip); MAKEFIELD(_T("名称"),_T("%s"),data.szName,sInfoTip); MAKEFIELD(_T("编号"),_T("%s"),data.szNo,sInfoTip); MAKEFIELD(_T("厂家"),_T("%s"),data.szFactory,sInfoTip); } else if (data.nType == 2) { sField = _T("窗:\n"); sInfoTip += sField; MAKEFIELD(_T("宽度"),_T("%.1f"),data.dWidth,sInfoTip); MAKEFIELD(_T("高度"),_T("%.1f"),data.dHeight,sInfoTip); MAKEFIELD(_T("相对墙底标高"),_T("%.1f"),data.dBomEl,sInfoTip); MAKEFIELD(_T("二维块名"),_T("%s"),data.szBlockName2d,sInfoTip); MAKEFIELD(_T("三维块名"),_T("%s"),data.szBlockName3d,sInfoTip); MAKEFIELD(_T("名称"),_T("%s"),data.szName,sInfoTip); MAKEFIELD(_T("编号"),_T("%s"),data.szNo,sInfoTip); MAKEFIELD(_T("厂家"),_T("%s"),data.szFactory,sInfoTip); } return true; } Acad::ErrorStatus AecDbXOpening::copyFrom(const AcRxObject* pSrc) { AecDbEntityBase::copyFrom(pSrc); AecDbXOpening* pSrcOp = AecDbXOpening::cast(pSrc); if (pSrcOp != NULL) { m_mapSpecXData.CopyFrom(&pSrcOp->m_mapSpecXData); //发送提资需要相同的ID Adesk::Int16 nVal = acdbCurDwg()->useri4(); if (nVal != KEY_NOPROTECT) { int nVt = 0; CString sID = IDCreate(); if (m_mapSpecXData.HasKey(KEY_NO, nVt)) m_mapSpecXData.SetAt(KEY_NO, sID); } } return Acad::eOk; } int AecDbXOpening::ComparedTo(AecDbEntityBase *pCurOther) const { assertReadEnabled(); AecDbXOpening *pOther = AecDbXOpening::cast(pCurOther); if (pOther != NULL) { /*//TEST AcDbHandle hdO; pOther->getAcDbHandle(hdO); AcDbHandle hdT; getAcDbHandle(hdT); TCHAR szO[17], szT[17]; hdO.getIntoAsciiBuffer(szO); hdT.getIntoAsciiBuffer(szT); acutPrintf(_T("\nThis:%s Other:%s"), szT, szO); */ OpeningData data1; GetOpeningData(data1); OpeningData data2; pOther->GetOpeningData(data2); if (fabs(data1.dWidth - data2.dWidth) > 1.e-1) return 1; if (fabs(data1.dHeight - data2.dHeight) > 1.e-1) return 1; if (fabs(data1.dThick - data2.dThick) > 1.e-1) return 1; if (fabs(data1.dBomEl - data2.dBomEl) > 1.e-1) return 1; if (_tcscmp(data1.szBlockName2d, data2.szBlockName2d) != 0) return 1; if (_tcscmp(data1.szBlockName3d, data2.szBlockName3d) != 0) return 1; if (_tcscmp(data1.szName, data2.szName) != 0) return 1; return 0; } return -1; } void AecDbXOpening::AlignInsPointToMidLine() { AcGePoint3d ptHit,ptOn; m_mapSpecXData.GetAt(KEY_PTON, ptHit); AcDbObjectId idWall; m_mapSpecXData.GetAt(KEY_IDCNT1, idWall); AcDbEntity *pEnt = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt, idWall, AcDb::kForRead)) { AecDbXWall *pWall = AecDbXWall::cast(pEnt); if (pWall != NULL) { double dThick = 10.0; pWall->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_SIZE1,dThick); AcDbCurve *pNaCur = NULL; AcDbLine *pNaLine = NULL; AcGeVector3d vtDir; AcGePoint3d ptSta, ptEnd, ptFr; double dDist1 = 0.0, dDist2 = 0.0; BOOL bIsVView = FALSE; pWall->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_VVIEW, bIsVView); if (bIsVView) { //1.创建整体Solid AcGePoint3d ptOnRegion; pWall->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_SECCEN, ptOnRegion); pNaCur = pWall->GetNativeCurve(); pNaCur->getStartPoint(ptSta); pNaCur->getEndPoint(ptEnd); AcGeVector3d vtNormal(AcGeVector3d::kIdentity); pNaCur->getFirstDeriv(ptSta, vtNormal); AcDbRegion *pCloneRegion = pWall->GetSection(); transfromRegion(pCloneRegion, ptOnRegion, vtNormal, ptEnd); AcDbLine *pLn1 = AecDbXWall::GetOrthoProjectOnXY(pCloneRegion); if (pLn1 != NULL) { AcGePoint3d ptMid, ptMid2; GetMidPoint(pNaCur, ptMid); ptMid.z = 0.0; pLn1->getClosestPointTo(ptMid, ptMid2); AcGeVector3d vtM = ptMid - ptMid2; AcGeMatrix3d xM; xM.setToTranslation(vtM); pLn1->transformBy(vtM); pLn1->getClosestPointTo(ptHit, ptOn); ptHit.z = ptOn.z = 0.0; if (ptHit.distanceTo(ptOn) < dThick) { m_mapSpecXData.SetAt(KEY_PTON, ptOn); } } delete pCloneRegion; } else { pNaCur = pWall->GetNativeCurve(); pNaCur->getClosestPointTo(ptHit, ptOn); ptHit.z = ptOn.z = 0.0; if (ptHit.distanceTo(ptOn) < dThick) { m_mapSpecXData.SetAt(KEY_PTON, ptOn); } } } pEnt->close(); } } Acad::ErrorStatus AecDbXOpening::subTransformBy(const AcGeMatrix3d& xform) { AssertWriteEnabled(); //当前命令如果时复制,不需要墙体原处合并 bool bIsCopy = false; if (objectId().isValid()) { struct resbuf rb; acedGetVar(_T("CMDNAMES"), &rb); if (_tcscmp(rb.resval.rstring, _T("COPY")) == 0) { bIsCopy = true; } } if (!bIsCopy) { PreRefreshWallDraw(); } AcGePoint3d ptPos; m_mapSpecXData.GetAt(KEY_ORGPT,ptPos); ptPos.transformBy(xform); m_mapSpecXData.SetAt(KEY_ORGPT,ptPos); //标高的变化 ptPos.set(0,0,0); m_mapSpecXData.GetAt(KEY_BOMEL,ptPos.z); ptPos.transformBy(xform); m_mapSpecXData.SetAt(KEY_BOMEL,ptPos.z); AcGeVector3d vtDir; m_mapSpecXData.GetAt(PIPE_DIR,vtDir); vtDir.normalize(); vtDir.transformBy(xform); m_mapSpecXData.SetAt(PIPE_DIR,vtDir); AcGePoint3d ptOn; m_mapSpecXData.GetAt(KEY_PTON,ptOn); ptOn.transformBy(xform); m_mapSpecXData.SetAt(KEY_PTON,ptOn); m_mapSpecXData.GetAt(KEY_NOPOS,ptOn); ptOn.transformBy(xform); m_mapSpecXData.SetAt(KEY_NOPOS,ptOn); if (objectId().isValid()) { if (objectId().isValid() && bIsCopy) { AlignInsPointToMidLine(); } //co 命令复制的门窗丢失了和墙体关系 //确认重新建立关系 AecComplexCurve win2d; GetStandardDraw2d(win2d, false); AcDbObjectId idWall; m_mapSpecXData.GetAt(KEY_IDCNT1, idWall); AcDbEntity *pEnt = NULL; if (Acad::eOk == acdbOpenAcDbEntity(pEnt, idWall, AcDb::kForWrite)) { AecDbXWall *pWall = AecDbXWall::cast(pEnt); if (pWall != NULL) { //pWall->AppendAssocPart(objectId()); } pEnt->close(); } } RefreshWallDraw(); return Acad::eOk; } CString AecDbXOpening::getUniqueName() const { assertReadEnabled(); CString str(_T("")); OpeningData data; ::memset(&data, 0, sizeof(OpeningData)); GetOpeningData(data); ::memset(&data.dBomEl, 0, sizeof(double)); ::memset(&data.ptPos, 0, sizeof(AcGePoint3d)); ::memset(data.szNo, 0, 65 * sizeof(TCHAR)); ::memset(data.szFactory, 0, MAX_PATH * sizeof(TCHAR)); byte *pBuf = new byte[sizeof(OpeningData)]; ::memset(pBuf, 0, sizeof(OpeningData)); memcpy(pBuf, &data, sizeof(OpeningData)); ImpMD5 md5(pBuf, sizeof(OpeningData)); return md5.toString16W().c_str(); } Acad::ErrorStatus AecDbXOpening::GetDoorOpenDir(AcGeVector3d& vtOpen) const { assertReadEnabled(); AcGeVector3d vtDir; m_mapSpecXData.GetAt(PIPE_DIR,vtDir); OpeningData data; GetOpeningData(data); //加载block2d AcDbObjectId idBlk2d; m_mapSpecXData.GetAt(KEY_BLK2DID,idBlk2d); AcDbBlockReference bRef; bRef.setBlockTableRecord(idBlk2d); bRef.setPosition(data.ptPos); int nDir = 1; m_mapSpecXData.GetAt(PIPE_TDIR,nDir); if (abs(nDir) < 1) nDir = 1; vtDir *= nDir; double dRot = AcGeVector3d::kXAxis.angleTo(vtDir,AcGeVector3d::kZAxis); bRef.setRotation(dRot); bRef.setScaleFactors( AcGeScale3d(data.dWidth,data.dWidth,1.0)); AcDbExtents ext; bRef.getGeomExtents(ext); AcGePoint3d ptMid = MidPoint(ext.minPoint(),ext.maxPoint()); ptMid.z = 0.0;data.ptPos.z = 0.0; vtOpen = ptMid - data.ptPos; double dLen = vtOpen.length() * 2.0; vtOpen.normalize(); vtOpen *= dLen; return Acad::eOk; } Acad::ErrorStatus AecDbXOpening::subGetGripPoints( AcDbGripDataPtrArray& grips, const double curViewUnitSize, const int gripSize, const AcGeVector3d& curViewDir, const int bitflags) const { assertReadEnabled(); AcGePoint3dArray gripPoints; ImpGetGripPoints(gripPoints,bitflags); int nColor = kWhite; AcDbGripData* pGripData = NULL; EPosition ePos; CString sTip; for (int i = 0;i < gripPoints.length();i++) { ePos = ExplainGripIndex(i,sTip); memset(&m_pGripAppData[i],0,sizeof(AecGripData)); m_pGripAppData[i].nIndex = i; m_pGripAppData[i].nSegIndex = -1; m_pGripAppData[i].ePos = ePos; m_pGripAppData[i].nColor = kBlue; m_pGripAppData[i].ptGrip = gripPoints.at(i); _tcscpy(m_pGripAppData[i].szTip,sTip); //_tcscpy(m_pGripAppData[i].szID,m_sGUID); m_pGripAppData[i].pOwner = (AcDbEntity*)this; pGripData = new AcDbGripData; pGripData->setGripPoint(gripPoints.at(i)); pGripData->setAppData((void*)&m_pGripAppData[i]); pGripData->setWorldDraw(AecGripCback::WorldDrawfunc); pGripData->setToolTipFunc(AecGripCback::GripToolTipFunc); grips.append(pGripData); } //调用基类加入单击修改 SubAddHitEditGrip(grips); //动态标注 //直线,半径 标注风格 if (!grips.isEmpty()) { SubAddDimPoints(grips, curViewDir); } return Acad::eOk; } Acad::ErrorStatus AecDbXOpening::SubAddDimPoints(AcDbGripDataPtrArray &grips, const AcGeVector3d &curViewDir) const { OpeningData opData; memset(&opData, 0, sizeof(OpeningData)); GetOpeningData(opData); AcGeVector3d vtDir; m_mapSpecXData.GetAt(PIPE_DIR, vtDir); vtDir.normalize(); AcGePoint3d ptS, ptE, ptPs,ptM; ptPs = opData.ptPos; //宽度 ptS = ptPs - 0.5 * vtDir * opData.dWidth; ptE = ptPs + 0.5 * vtDir * opData.dWidth; ptM = MidPoint(ptS, ptE); ptM.z -= 5.0 * 100.0;//标注文字位置 AddDimPoints(grips, curViewDir, ptS, ptE, ptM, 0); //高度 ptS = ptPs + AcGeVector3d::kZAxis * opData.dHeight; ptE = ptPs; ptM = MidPoint(ptS, ptE); ptM += 5.0 * 200.0 * vtDir;//标注文字位置 AddDimPoints(grips, curViewDir, ptS, ptE, ptM, 0); return Acad::eOk; } Acad::ErrorStatus AecDbXOpening::AddDimPoints(AcDbGripDataPtrArray &grips, const AcGeVector3d &curViewDir, const AcGePoint3d &ptSta, const AcGePoint3d &ptEnd, const AcGePoint3d &ptMid, int nDimType, double dVal/* = -1.0*/, double dt) const { int i = grips.length(); if (i >= GRIP_LENGTH)//多余不显示 return Acad::eOk; EPosition ePos = eDim0; memset(&m_pGripAppData[i], 0, sizeof(AecGripData)); m_pGripAppData[i].nIndex = i; m_pGripAppData[i].ePos = ePos; m_pGripAppData[i].nColor = kGreen; m_pGripAppData[i].ptGrip = ptMid; m_pGripAppData[i].ptDim[0] = ptSta; m_pGripAppData[i].ptDim[1] = ptEnd; m_pGripAppData[i].nDimType = nDimType; if (dVal > 1.e-3) { if (nDimType == 1) { _stprintf(m_pGripAppData[i].szTip, _T("R%.1f"), dVal); } else if (nDimType == 2)//@100 标注 { _stprintf(m_pGripAppData[i].szTip, _T("Ø%.1f"), dVal); } else if (nDimType == 3)//角度标注 { _stprintf(m_pGripAppData[i].szTip, _T("%.1f°"), dVal); } else if (nDimType == 4)//@107x3.5 { _stprintf(m_pGripAppData[i].szTip, _T("Ø%.1fx%.1f"), dVal, dt); } } else { _tcscpy(m_pGripAppData[i].szTip, _T(" ")); } _tcscpy(m_pGripAppData[i].szID, _T(" ")); m_pGripAppData[i].pOwner = (AcDbEntity *)this; AcDbGripData *pGripData = new AcDbGripData; pGripData->setGripPoint(ptMid); pGripData->setAppData((void *)&m_pGripAppData[i]); pGripData->setWorldDraw(AecGripCback::WorldDrawfunc); pGripData->setToolTipFunc(AecGripCback::GripToolTipFunc); grips.append(pGripData); return Acad::eOk; } Acad::ErrorStatus AecDbXOpening::ImpGetGripPoints(AcGePoint3dArray& gripPoints,const int bitflags) const { assertReadEnabled(); AcGePoint3d ptPos; m_mapSpecXData.GetAt(KEY_ORGPT,ptPos); ptPos.z = 0.0; AcGePoint3d ptGe[5]; OpeningData data; GetOpeningData(data); ptGe[0] = ptPos; AcGeVector3d vtDir; m_mapSpecXData.GetAt(PIPE_DIR,vtDir); vtDir.normalize(); ptGe[1] = ptGe[0] - data.dWidth * 0.5 * vtDir; ptGe[2] = ptGe[0] + data.dWidth * 0.5 * vtDir; AcGeVector3d vtOpen; GetDoorOpenDir(vtOpen); ptGe[3] = ptGe[0] + vtOpen; for (int i = 0;i < 4;i++) { gripPoints.append(ptGe[i]); } m_mapSpecXData.GetAt(KEY_NOPOS,ptPos); gripPoints.append(ptPos); //增加左右,如果是門 if (data.nType == 2) { //左右方向 int nLDir = 1; m_mapSpecXData.GetAt(PIPE_DRAWDIR, nLDir); if (abs(nLDir) < 1) nLDir = 1; if (abs(nLDir) > 1) nLDir = nLDir / abs(nLDir); vtDir.normalize(); vtDir *= vtOpen.length(); ptGe[4] = ptGe[3] + vtDir * nLDir; gripPoints.append(ptGe[4]); } return Acad::eOk; } EPosition AecDbXOpening::ExplainGripIndex(int nIndex,CString& sTip) const { assertReadEnabled(); EPosition ePos = eAdjust0; switch(nIndex) { case 0://Mid { ePos = eMid; sTip = _T("门窗的位置点"); break; } case 1://Sta { ePos = eStart; sTip = _T("门窗的左侧改宽度点"); break; } case 2://End { ePos = eEnd; sTip = _T("门窗的右侧改宽度点"); break; } case 3://Open { ePos = eAdjust0; sTip = _T("门窗的开口方向点"); break; } case 4: { ePos = eAdjust0; sTip = _T("门窗的编号位置点"); break; } case 5: { ePos = eAdjust0; sTip = _T("门窗的左右方向点"); break; } default: break; } return ePos; } bool AecDbXOpening::GetPositionGrip(int nIndex, AecGripData *&pGrip) const { if (nIndex < GRIP_LENGTH && nIndex >= 0) { pGrip = &m_pGripAppData[nIndex]; return true; } return false; } Acad::ErrorStatus AecDbXOpening::subMoveGripPointsAt(const AcDbVoidPtrArray& appData, const AcGeVector3d& offset, const int bitflags) { AssertWriteEnabled(); if (!appData.isEmpty()) { if (HitOnGripEdit(appData)) { return Acad::eOk; } AecGripData* pAppData = NULL; if ( appData.isEmpty() ) { return Acad::eOk; } AcGeVector3d vtDir,vtOpen; m_mapSpecXData.GetAt(PIPE_DIR,vtDir); vtDir.normalize(); double dW = 0.0,dDis1 = 0,dDis2 = 0; AcGePoint3d ptOn,ptPos,ptTmp; AcGeVector3d vtOffset; pAppData = (AecGripData*)appData.first(); AcGePoint3d ptHit = pAppData->ptGrip; int nGripIndex = pAppData->nIndex; switch(nGripIndex) { case 0://Mid { if (bitflags != 999) PreRefreshWallDraw(); vtDir.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); vtOffset = offset.orthoProject(vtDir); m_mapSpecXData.GetAt(KEY_PTON,ptOn); ptOn += vtOffset; m_mapSpecXData.SetAt(KEY_PTON,ptOn); m_mapSpecXData.GetAt(KEY_ORGPT,ptPos); ptPos += vtOffset; m_mapSpecXData.SetAt(KEY_ORGPT,ptPos); if (m_mapSpecXData.GetAt(KEY_NOPOS,ptOn)) { ptOn += vtOffset; m_mapSpecXData.SetAt(KEY_NOPOS,ptOn); } if (bitflags != 999) RefreshWallDraw(); break; } case 1://Sta case 2://End { if (bitflags != 999) PreRefreshWallDraw(); //宽度变化,位置不变 vtDir.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); vtOffset = offset.orthoProject(vtDir); m_mapSpecXData.GetAt(KEY_ORGPT,ptPos); ptTmp = ptPos; ptPos += 0.5 * vtOffset; m_mapSpecXData.SetAt(KEY_ORGPT,ptPos); m_mapSpecXData.GetAt(KEY_PTON,ptOn); ptOn += 0.5 * vtOffset; m_mapSpecXData.SetAt(KEY_PTON,ptOn); //ptPos.z = 0.0; //ptHit += vtOffset; //ptHit.z = 0.0; //dW = 2.0 * ptHit.distanceTo(ptPos); ptTmp.z = 0.0; dDis1 = ptHit.distanceTo(ptTmp); ptHit += vtOffset; dDis2 = ptHit.distanceTo(ptTmp); //单边改变宽度 m_mapSpecXData.GetAt(KEY_Width,dW); dW -= (dDis1 - dDis2); m_mapSpecXData.SetAt(KEY_Width,dW); if (bitflags != 999) RefreshWallDraw(); break; } case 3://Open { vtOffset = offset.orthoProject(vtDir); GetDoorOpenDir(vtOpen); int nDir = 1; m_mapSpecXData.GetAt(PIPE_TDIR,nDir); if (abs(nDir) < 1) nDir = 1; vtOpen *= nDir; if ( !vtOffset.isZeroLength()) { if ( vtOffset.isCodirectionalTo(vtOpen) )//同向 { m_mapSpecXData.SetAt(PIPE_TDIR,1); } else { m_mapSpecXData.SetAt(PIPE_TDIR,-1); } } break; } case 4://lable { m_mapSpecXData.GetAt(KEY_NOPOS,ptOn); ptOn += offset; m_mapSpecXData.SetAt(KEY_NOPOS,ptOn); break; } case 5: { int nDir = 1; m_mapSpecXData.GetAt(PIPE_DRAWDIR, nDir); GetDoorOpenDir(vtOpen); vtOffset = offset.orthoProject(vtOpen); vtDir *= nDir; if (!vtOffset.isZeroLength() && vtOffset.dotProduct(vtDir) < 0) { nDir *= -1; } m_mapSpecXData.SetAt(PIPE_DRAWDIR, nDir); break; } default: break; } } return Acad::eOk; } Acad::ErrorStatus AecDbXOpening::subGetStretchPoints(AcGePoint3dArray& stretchPoints) const { assertReadEnabled(); AcGePoint3d ptPos; m_mapSpecXData.GetAt(KEY_ORGPT,ptPos); ptPos.z = 0.0; stretchPoints.append(ptPos); return Acad::eOk; } Acad::ErrorStatus AecDbXOpening::subMoveStretchPointsAt(const AcDbIntArray& indices,const AcGeVector3d& offset) { AssertWriteEnabled(); AcGeVector3d vtDir,vtOpen; m_mapSpecXData.GetAt(PIPE_DIR,vtDir); vtDir.normalize(); double dW = 0.0; AcGePoint3d ptOn,ptPos; AcGeVector3d vtOffset; int nGripIndex = indices.first(); switch(nGripIndex) { case 0://Mid { PreRefreshWallDraw(); vtDir.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); vtOffset = offset;//offset.orthoProject(vtDir); m_mapSpecXData.GetAt(KEY_PTON,ptOn); ptOn += vtOffset; m_mapSpecXData.SetAt(KEY_PTON,ptOn); m_mapSpecXData.GetAt(KEY_ORGPT,ptPos); ptPos += vtOffset; m_mapSpecXData.SetAt(KEY_ORGPT,ptPos); RefreshWallDraw(); break; } default: break; } return Acad::eOk; } Acad::ErrorStatus AecDbXOpening::PreRefreshWallDraw() { if (objectId().isValid()) { AcDbObjectId idWall; m_mapSpecXData.GetAt(KEY_IDCNT1,idWall); Acad::ErrorStatus es; AcDbEntity* pEnt = NULL; if ( Acad::eOk == ( es = acdbOpenAcDbEntity(pEnt,idWall,AcDb::kForWrite))) { AecDbXWall* pWall = AecDbXWall::cast(pEnt); if (pWall != NULL) { AecComplexCurve win2d; GetStandardDraw2d(win2d,false); pWall->BoolUniteDraw2d(win2d); } pEnt->close(); } } return Acad::eOk; } void AecDbXOpening::RefreshWallOnOpeningDraw(const AcDbObjectId &idWall ) { assertReadEnabled(); Acad::ErrorStatus es; AcDbEntity *pEnt = NULL; if (Acad::eOk == (es = acdbOpenAcDbEntity(pEnt, idWall, AcDb::kForWrite))) { AecDbXWall *pWall = AecDbXWall::cast(pEnt); if (pWall != NULL) { AecComplexCurve win2d; this->GetStandardDraw2d(win2d, false); pWall->SubtractDraw2d(win2d); } pEnt->close(); } } Acad::ErrorStatus AecDbXOpening::RefreshWallDraw() { if (objectId().isValid()) { AcDbObjectId idWall; m_mapSpecXData.GetAt(KEY_IDCNT1,idWall); //新的更新墙体方式解决co的复制中断 RefreshWallOnOpeningDraw(idWall); return Acad::eOk; //消息方式,导致co的复制多次中断 GripMessage msg; memset(&msg,0,sizeof(GripMessage)); msg.nType = kGripMsgContinue;//跳过 GipCmdEnd,为 PL_MQSX用 msg.idHost = idWall; msg.idAsso = objectId(); msg.nData = 0; msg.pParam = NULL; msg.fData = 0.0; msg.ptGrip.set(0,0,0); PushGripMessage(msg); acedPostCommand(_T("\x03")); acedPostCommand(_T("PL_MQSX\n")); } return Acad::eOk; } Acad::ErrorStatus AecDbXOpening::subIntersectWith( const AcDbEntity* pEnt, AcDb::Intersect intType, AcGePoint3dArray& points, INT_PTR thisGsMarker, INT_PTR otherGsMarker) const { assertReadEnabled(); AcDbEntity* pEntT = NULL; const AcDbVoidPtrArray& ar2D = Get2DBuffer(); AcGePoint3dArray arPts1; for (int i = 0;i < ar2D.length();i++) { pEntT = (AcDbEntity*)ar2D.at(i); pEntT->intersectWith(pEnt,intType,points,thisGsMarker,otherGsMarker); } return Acad::eOk; } Acad::ErrorStatus AecDbXOpening::subIntersectWith( const AcDbEntity* pEnt, AcDb::Intersect intType, const AcGePlane& projPlane, AcGePoint3dArray& points, INT_PTR thisGsMarker, INT_PTR otherGsMarker) const { assertReadEnabled(); AcDbEntity* pEntT = NULL; const AcDbVoidPtrArray& ar2D = Get2DBuffer(); AcGePoint3dArray arPts1; for (int i = 0;i < ar2D.length();i++) { pEntT = (AcDbEntity*)ar2D.at(i); pEntT->intersectWith(pEnt,intType,projPlane,points,thisGsMarker,otherGsMarker); } return Acad::eOk; } AcGeScale3d AecDbXOpening::GetBlockToIdentity(const AcDbObjectId& idRec) const { assertReadEnabled(); AcDbBlockReference bRef; bRef.setBlockTableRecord(idRec); bRef.setPosition(AcGePoint3d::kOrigin); bRef.setRotation(0.0); bRef.setScaleFactors(AcGeScale3d(1,1,1)); AcDbExtents ext; bRef.getGeomExtents(ext); AcGeScale3d scale; scale.sx = 1.0 / (ext.maxPoint().x - ext.minPoint().x); scale.sy = 1.0 / (ext.maxPoint().y - ext.minPoint().y); scale.sz = 1.0; if ( (ext.maxPoint().z - ext.minPoint().z ) > 1.e-6) { scale.sz = 1.0 / (ext.maxPoint().z - ext.minPoint().z); } return scale; } bool AecDbXOpening::GetStandardDraw2d(AecComplexCurve& draw2d,bool bHasEnd/* = true*/) const { int nGroup = 0; m_mapSpecXData.GetAt(KEY_FLAG,nGroup); int nType = 0; m_mapSpecXData.GetAt(KEY_TYPE,nType); double dWidth = 0.0; m_mapSpecXData.GetAt(KEY_Width,dWidth); AcGeVector3d vtDir; m_mapSpecXData.GetAt(PIPE_DIR,vtDir); AcGePoint3d ptOn; m_mapSpecXData.GetAt(KEY_PTON,ptOn); double dThick = 0.0; m_mapSpecXData.GetAt(KEY_THICK,dThick); AecEqui::AecCurveElement el; memset(&el,0,sizeof(AecEqui::AecCurveElement)); AcGeVector3d vtV = vtDir; vtV.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); ptOn.z = 0.0; vtDir.normalize(); AcGePoint3d ptGe[5]; ptGe[0] = ptOn; ptGe[0] -= vtDir * 0.5 * dWidth; ptGe[0] += vtV * 0.5 * dThick; ptGe[1] = ptGe[0] + vtDir * dWidth; ptGe[2] = ptGe[1] - vtV * dThick; ptGe[3] = ptGe[2] - vtDir * dWidth; ptGe[4] = ptGe[0]; if (bHasEnd) { el.ptGe[0] = ptGe[0]; el.ptGe[1] = ptGe[1]; el.ptGe[2] = ptGe[1]; el.gsMark = 1; draw2d.append(el); el.ptGe[0] = ptGe[3]; el.ptGe[1] = ptGe[2]; el.ptGe[2] = ptGe[2]; el.gsMark = 1; draw2d.append(el); if (nGroup == 1)// 是组合门窗 { } else { el.ptGe[0] = ptGe[3]; el.ptGe[1] = ptGe[0]; el.ptGe[2] = ptGe[0]; el.gsMark = 0; draw2d.append(el); el.ptGe[0] = ptGe[1]; el.ptGe[1] = ptGe[2]; el.ptGe[2] = ptGe[2]; el.gsMark = 0; draw2d.append(el); } } else { el.ptGe[0] = ptGe[0]; el.ptGe[1] = ptGe[1]; el.ptGe[2] = ptGe[1]; draw2d.append(el); el.ptGe[0] = ptGe[3]; el.ptGe[1] = ptGe[2]; el.ptGe[2] = ptGe[2]; draw2d.append(el); } return true; } void AecDbXOpening::GetSideLines(AecComplexCurve& draw2d,const AcGeVector3d& vtDir) const { int nGroup = 0; m_mapSpecXData.GetAt(KEY_FLAG,nGroup); int nType = 0; m_mapSpecXData.GetAt(KEY_TYPE,nType); double dWidth = 0.0; m_mapSpecXData.GetAt(KEY_Width,dWidth); AcGePoint3d ptOn; m_mapSpecXData.GetAt(KEY_PTON,ptOn); double dThick = 0.0; m_mapSpecXData.GetAt(KEY_THICK,dThick); AecEqui::AecCurveElement el; memset(&el,0,sizeof(AecEqui::AecCurveElement)); AcGeVector3d vtV = vtDir; vtV.rotateBy(PI / 2.0,AcGeVector3d::kZAxis); ptOn.z = 0.0; AcGePoint3d ptGe[5]; ptGe[0] = ptOn; ptGe[0] -= vtDir * 0.5 * dWidth; ptGe[0] += vtV * 0.5 * dThick; ptGe[1] = ptGe[0] + vtDir * dWidth; ptGe[2] = ptGe[1] - vtV * dThick; ptGe[3] = ptGe[2] - vtDir * dWidth; ptGe[4] = ptGe[0]; el.ptGe[0] = ptGe[3]; el.ptGe[1] = ptGe[0]; el.ptGe[2] = ptGe[0]; el.gsMark = 0; draw2d.append(el); el.ptGe[0] = ptGe[1]; el.ptGe[1] = ptGe[2]; el.ptGe[2] = ptGe[2]; el.gsMark = 0; draw2d.append(el); } int AecDbXOpening::GetDraw2dables(Adesk::UInt16 nDrawStyle, AcDbVoidPtrArray& arEntPtrs) const { assertReadEnabled(); OpeningData data; GetOpeningData(data); AcDbObjectId idBlk2d; m_mapSpecXData.GetAt(KEY_BLK2DID,idBlk2d); if (idBlk2d.isValid()) { AcGeVector3d vtDir(1,0,0); AcGePoint3d ptPos,ptOn; ptPos = data.ptPos; ptPos.z = 0.0; WallData wData; memset(&wData,0,sizeof(WallData)); AcDbObjectId idWall; m_mapSpecXData.GetAt(KEY_IDCNT1,idWall); if (idWall.isValid()) { AcDbEntity* pEnt = NULL; AecDbXWall* pWall = NULL; if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,idWall,AcDb::kForRead)) { pWall = AecDbXWall::cast(pEnt); if (pWall != NULL) { AcDbCurve* pNaCur = pWall->GetNativeCurve(); if ( pNaCur != NULL) { pNaCur->getClosestPointTo(ptPos,ptOn); pNaCur->getFirstDeriv(ptOn,vtDir); pWall->GetWallData(wData); } } pEnt->close(); } } double dRot = AcGeVector3d::kXAxis.angleTo(vtDir,AcGeVector3d::kZAxis); //acutPrintf(_T("\nrot = %g"),dRot); //AcGeScale3d scale = GetBlockToIdentity(idBlk2d); AcGeScale3d scl2d; scl2d.set(data.dWidth,wData.dThick,1.0); if (data.nType == kDoor) { scl2d.set(data.dWidth,data.dWidth,1.0); } else { scl2d.set(data.dWidth,wData.dThick,1.0); } //dc.DrawBlock(idBlk2d,ptPos,scl2d,dRot,FALSE); AcDbBlockReference* pRef = new AcDbBlockReference; pRef->setBlockTableRecord(idBlk2d); pRef->setPosition(ptPos); pRef->setScaleFactors(scl2d); pRef->setRotation(dRot); pRef->setLayer(layerId()); arEntPtrs.append(pRef); AecComplexCurve win2d; GetStandardDraw2d(win2d,true); //测试 /*AcDbLine* pLn = NULL; for (int i = 0;i < win2d.length();i++) { AecEqui::AecCurveElement& el = win2d.atByRef(i); if ( AecComplexCurve::MakeLine(el,pLn) ) { pLn->setColorIndex(3); CKTCadUtility::AddToBlockTableRecord(pLn); pLn->close(); } }*/ AecComplexCurve win2dEnd; for (int i = 0;i < win2d.length();i++) { AecEqui::AecCurveElement& el = win2d.atByRef(i); if (el.gsMark == 0) { win2dEnd.append(el); } } //设置为墙体的图层 AcDbObjectId idWallLay = KTSetting::InitLayer(_T("LAY_WALL"),true); AecComplexCurveDraw win2dEndDraw; win2dEndDraw.SetEdage(win2dEnd); win2dEndDraw.explode(arEntPtrs,idWallLay,idWallLay,idWallLay); CString sLable = GetLabel(); if (!sLable.IsEmpty() && sLable.CompareNoCase(_T("No")) != 0 ) { AcDbObjectId id = acdbCurDwg()->textstyle(); AcDbText* pText = new AcDbText; pText->setTextStyle(id); pText->setLayer(layerId()); pText->setWidthFactor(0.75); double dScale = 100.0; GetDocScale(dScale); pText->setHeight(2.5 * dScale); pText->setTextString(GetLabel()); m_mapSpecXData.GetAt(KEY_NOPOS,ptOn); pText->setPosition(ptOn); pText->setHorizontalMode(AcDb::kTextCenter); pText->setAlignmentPoint(ptOn); arEntPtrs.append(pText); } } return arEntPtrs.length(); } AcDbObjectId AecDbXOpening::LoadOpeningBlk2d() const { assertReadEnabled(); AcDbObjectId idBlock2d; CString sBlockName2d; m_mapSpecXData.GetAt(KEY_BLK2D,sBlockName2d); CString sBlockName3d; m_mapSpecXData.GetAt(KEY_BLK3D,sBlockName3d); OpeningData data; memset(&data,0,sizeof(OpeningData)); m_mapSpecXData.GetAt(KEY_TYPE,data.nType); CString sDbtxtFile = _T("DoorDb.txt"); if (data.nType == 1)//窗 { sDbtxtFile = _T("WindowDb.txt"); } CString sPath,sPath2,_sDwgFile; KTSetting::GetKTPsPath(sPath); sPath += _T("Support\\Cells\\"); sPath2 = sPath; sPath += sDbtxtFile; CString sDwgFile,sRecName,sRecName3D; int nIndex = -1,nIndex2 = -1; CStdioFile file; if (file.Open(sPath,CFile::modeRead)) { CString sText,sTmp; while(file.ReadString(sText)) { if (sText.FindOneOf(_T("//")) != -1) { continue; } nIndex = sText.Find(_T(';')); if (nIndex != -1) { //WIN1.dwg;KTWIN01;KTWIN01_3D sDwgFile = sText.Mid(0,nIndex); sTmp = sText.Mid(nIndex + 1); nIndex2 = sTmp.ReverseFind(_T(';')); if (nIndex2 != -1) { sRecName = sTmp.Mid(0,nIndex2); } nIndex = sText.ReverseFind(_T(';')); if (nIndex != -1) { sRecName3D = sText.Mid(nIndex+1); } if ( sRecName.CompareNoCase(sBlockName2d) == 0 && sRecName3D.CompareNoCase(sBlockName3d) == 0 ) { _sDwgFile = sDwgFile; break; } } } file.Close(); } if (!_sDwgFile.IsEmpty()) { sDwgFile = _T(""); KTSetting::GetKTPsPath(sDwgFile); sDwgFile += _T("Support\\Cells\\"); sDwgFile += _sDwgFile; AcDbDatabase* pDb = new AcDbDatabase(false); ASSERT(pDB != NULL); if (pDb->readDwgFile(sDwgFile, AcDbDatabase::kForReadAndAllShare) != Acad::eOk) { delete pDb; return idBlock2d; } AcDbBlockTable* pBT = NULL; pDb->getSymbolTable(pBT, AcDb::kForRead); if (pBT == NULL) { delete pDb; return idBlock2d; } AcDbObjectId idBlock; pBT->getAt(sBlockName2d, idBlock); pBT->close(); AcDbDatabase* pTempDb = NULL; pDb->wblock(pTempDb, idBlock); delete pDb; if (pTempDb == NULL) return FALSE; AcDbDatabase* pWorkDb = acdbHostApplicationServices()->workingDatabase(); if (pWorkDb->insert(idBlock2d, sBlockName2d, pTempDb) != Acad::eOk) { delete pTempDb; return idBlock2d; } delete pTempDb; } return idBlock2d; } AcDbObjectId AecDbXOpening::LoadOpeningBlk3d() const { assertReadEnabled(); AcDbObjectId idBlock3d; CString sBlockName2d; m_mapSpecXData.GetAt(KEY_BLK2D,sBlockName2d); CString sBlockName3d; m_mapSpecXData.GetAt(KEY_BLK3D,sBlockName3d); OpeningData data; memset(&data,0,sizeof(OpeningData)); m_mapSpecXData.GetAt(KEY_TYPE,data.nType); CString sDbtxtFile = _T("DoorDb.txt"); if (data.nType == 1)//窗 { sDbtxtFile = _T("WindowDb.txt"); } CString sPath,sPath2,_sDwgFile,_sDwg3DFile; KTSetting::GetKTPsPath(sPath); sPath += _T("Support\\Cells\\"); sPath2 = sPath; sPath += sDbtxtFile; CString sDwgFile,sRecName,sRecName3D; int nIndex = -1,nIndex2 = -1; CStdioFile file; if (file.Open(sPath,CFile::modeRead)) { CString sText,sTmp; while(file.ReadString(sText)) { if (sText.FindOneOf(_T("//")) != -1) { continue; } nIndex = sText.Find(_T(';')); if (nIndex != -1) { //WIN1.dwg;KTWIN01;KTWIN01_3D sDwgFile = sText.Mid(0,nIndex); sTmp = sText.Mid(nIndex + 1); nIndex2 = sTmp.ReverseFind(_T(';')); if (nIndex2 != -1) { sRecName = sTmp.Mid(0,nIndex2); } nIndex = sText.ReverseFind(_T(';')); if (nIndex != -1) { sRecName3D = sText.Mid(nIndex+1); } if ( sRecName.CompareNoCase(sBlockName2d) == 0 && sRecName3D.CompareNoCase(sBlockName3d) == 0 ) { _sDwg3DFile = sDwgFile; _sDwg3DFile.MakeLower(); _sDwg3DFile.TrimRight(_T(".dwg")); _sDwg3DFile += _T("_3D.dwg"); break; } } } file.Close(); } if (!_sDwg3DFile.IsEmpty()) { sDwgFile = _T(""); KTSetting::GetKTPsPath(sDwgFile); sDwgFile += _T("Support\\Cells\\"); sDwgFile += _sDwg3DFile; AcDbDatabase* pDb = new AcDbDatabase(false); ASSERT(pDB != NULL); if (pDb->readDwgFile(sDwgFile, AcDbDatabase::kForReadAndAllShare) != Acad::eOk) { delete pDb; return FALSE; } AcDbBlockTable* pBT = NULL; pDb->getSymbolTable(pBT, AcDb::kForRead); if (pBT == NULL) { delete pDb; return idBlock3d; } AcDbObjectId idBlock; pBT->getAt(sBlockName3d, idBlock); pBT->close(); AcDbDatabase* pTempDb = NULL; pDb->wblock(pTempDb, idBlock); delete pDb; if (pTempDb == NULL) return FALSE; AcDbDatabase* pWorkDb = acdbHostApplicationServices()->workingDatabase(); if (pWorkDb->insert(idBlock3d, sBlockName3d, pTempDb) != Acad::eOk) { delete pTempDb; return idBlock3d; } delete pTempDb; } return idBlock3d; } AcDbObjectId AecDbXOpening::LoadOpeningSectionDrawBlk2d() const { assertReadEnabled(); AcDbObjectId idBlock2d; OpeningData data; memset(&data, 0, sizeof(OpeningData)); m_mapSpecXData.GetAt(KEY_TYPE, data.nType); //固定 CString sBlockName2d = _T("14$墙内推拉门"); if (data.nType == 1)//窗 { sBlockName2d = _T("0$通用剖面门窗"); } //先从当前db查 AcDbBlockTable *pBT = NULL; AcDbDatabase *pDbCur = acdbCurDwg(); pDbCur->getSymbolTable(pBT, AcDb::kForRead); if (pBT == NULL) { return idBlock2d; } if (Acad::eOk == pBT->getAt(sBlockName2d, idBlock2d)) { pBT->close(); return idBlock2d; } else { pBT->close(); } //加载 CString sDwgFile = _T(""); KTSetting::GetKTPsPath(sDwgFile); sDwgFile += _T("Support\\Cells\\剖面门窗.dwg"); AcDbDatabase *pDb = new AcDbDatabase(false); ASSERT(pDB != NULL); if (pDb->readDwgFile(sDwgFile, AcDbDatabase::kForReadAndAllShare) != Acad::eOk) { delete pDb; return idBlock2d; } pDb->getSymbolTable(pBT, AcDb::kForRead); if (pBT == NULL) { delete pDb; return idBlock2d; } AcDbObjectId idBlock; pBT->getAt(sBlockName2d, idBlock); pBT->close(); AcDbDatabase *pTempDb = NULL; pDb->wblock(pTempDb, idBlock); delete pDb; if (pTempDb == NULL) return FALSE; AcDbDatabase *pWorkDb = acdbHostApplicationServices()->workingDatabase(); if (pWorkDb->insert(idBlock2d, sBlockName2d, pTempDb) != Acad::eOk) { delete pTempDb; return idBlock2d; } delete pTempDb; return idBlock2d; } Acad::ErrorStatus AecDbXOpening::Draw2d(AcGiDraw &dc) const { assertReadEnabled(); AcDbObjectId idCurLay = dc.GetLayerId(); AcDbObjectId idCurLty = dc.GetLineTypeId(); Adesk::UInt16 nCrBk = colorIndex(); dc.SetLayer(layerId()); int nColor = nCrBk; if ( m_mapSpecXData.GetAt(_T("COLOR"),nColor) ) { dc.SetColor(nColor); } //二维缓存,未知出错! if (Has2DBuffer()) { Draw2DBuffers(dc); //绘制编号 CString sLable = GetLabel(); sLable.TrimRight(_T(" ")); if (!sLable.IsEmpty() && sLable.CompareNoCase(_T("No")) != 0) { if (sLable.GetLength() < 36)//GetWallData(wData); BOOL bIsVView = FALSE; pWall->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_VVIEW,bIsVView); if (bIsVView) { //1.创建整体Solid AcGePoint3d ptOnRegion; pWall->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_SECCEN,ptOnRegion); AcDbCurve* pNaCur = pWall->GetNativeCurve(); AcGePoint3d ptSta,ptEnd; pNaCur->getStartPoint(ptSta); pNaCur->getEndPoint(ptEnd); AcGeVector3d vtNormal(AcGeVector3d::kIdentity); pNaCur->getFirstDeriv(ptSta, vtNormal); AcDbRegion* pCloneRegion = pWall->GetSection(); transfromRegion(pCloneRegion, ptOnRegion, vtNormal, ptEnd); AcDbLine* pLn1 = AecDbXWall::GetOrthoProjectOnXY(pCloneRegion); if (pLn1 != NULL) { AcGePoint3d ptMid,ptMid2; GetMidPoint(pNaCur,ptMid); ptMid.z = 0.0; pLn1->getClosestPointTo(ptMid,ptMid2); AcGeVector3d vtM = ptMid - ptMid2; AcGeMatrix3d xM;xM.setToTranslation(vtM); pLn1->transformBy(vtM); pNaLine = pLn1; } delete pCloneRegion; } pNaCur = pWall->GetNativeCurve(); if (pNaLine != NULL) { pNaLine->getClosestPointTo(ptPos,ptOn); pNaLine->getFirstDeriv(ptOn,vtDir); } else { if ( pNaCur != NULL) { pNaCur->getClosestPointTo(ptPos,ptOn); pNaCur->getFirstDeriv(ptOn,vtDir); } } } pEnt->close(); } } AcGeScale3d scl2d; scl2d.set(data.dWidth,wData.dThick,1.0); //开口方向 int nDir = 1; m_mapSpecXData.GetAt(PIPE_TDIR,nDir); if (abs(nDir) < 1) nDir = 1; if (abs(nDir) > 1) nDir = nDir / abs(nDir); //左右方向 int nLDir = 1; m_mapSpecXData.GetAt(PIPE_DRAWDIR, nLDir); if (abs(nLDir) < 1) nLDir = 1; if (abs(nLDir) > 1) nLDir = nLDir / abs(nLDir); double dRot = AcGeVector3d::kXAxis.angleTo(vtDir,AcGeVector3d::kZAxis); //acutPrintf(_T("\nrot = %g"),dRot); //AcGeScale3d scale = GetBlockToIdentity(idBlk2d); if (data.nType == kDoor) { scl2d.set(data.dWidth * nLDir,data.dWidth * nDir,1.0); dRot = AcGeVector3d::kXAxis.angleTo(vtDir, AcGeVector3d::kZAxis); } else { scl2d.set(data.dWidth,wData.dThick,1.0); } dc.DrawBlock(idBlk2d,ptPos,scl2d,dRot,FALSE); //块引用分解到体 AcDbBlockReference* pRef = new AcDbBlockReference; pRef->setBlockTableRecord(idBlk2d); pRef->setPosition(ptPos); pRef->setRotation(dRot); pRef->setScaleFactors(scl2d); pRef->setLayer(layerId()); if (data.nType == 1) pRef->setColorIndex(4); Add2DBuffer(pRef); //门的裁剪墙线预先在插入门的时候; AecComplexCurve win2d; GetStandardDraw2d(win2d,true); //测试 /*AcDbLine* pLn = NULL; for (int i = 0;i < win2d.length();i++) { AecEqui::AecCurveElement& el = win2d.atByRef(i); if ( AecComplexCurve::MakeLine(el,pLn) ) { pLn->setColorIndex(3); CKTCadUtility::AddToBlockTableRecord(pLn); pLn->close(); } }*/ AecComplexCurve win2dEnd; for (int i = 0;i < win2d.length();i++) { AecEqui::AecCurveElement& el = win2d.atByRef(i); if (el.gsMark == 0) { win2dEnd.append(el); } } //设置为墙体的图层 AcDbObjectId idWallLay = KTSetting::InitLayer(_T("LAY_WALL"),true); AecComplexCurveDraw win2dEndDraw; win2dEndDraw.SetEdage(win2dEnd); win2dEndDraw.Draw2d(dc,idWallLay,idWallLay,idWallLay); AcDbVoidPtrArray arDraw2d; win2dEndDraw.explode(arDraw2d, idWallLay, idWallLay, idWallLay); Add2DBuffer(arDraw2d); //绘制编号 CString sLable = GetLabel(); sLable.TrimRight(_T(" ")); if (!sLable.IsEmpty() && sLable.CompareNoCase(_T("No")) != 0 ) { if ( sLable.GetLength() < 36)//textstyle(); AcDbText* pText = new AcDbText; pText->setTextStyle(id); pText->setLayer(layerId()); pText->setWidthFactor(0.75); double dScale = 100.0; GetDocScale(dScale); pText->setHeight(2.5 * dScale); pText->setTextString(pszLab); AcGePoint3d ptOn; m_mapSpecXData.GetAt(KEY_NOPOS,ptOn); pText->setPosition(ptOn); pText->setHorizontalMode(AcDb::kTextCenter); pText->setAlignmentPoint(ptOn); dc.DrawEntity(*pText); delete pText;//? return Acad::eOk; } AcDb3dSolid* FaceToSolid(AcDbFace* pFace, std::vector *pSos = NULL) { AcDb3dSolid* pSolid = NULL; if (pFace != NULL) { AcGePoint3d pt; AcGePoint3dArray arPts; AcDbVoidPtrArray arLnPtrs,arRegPtrs; for (int i = 0;i < 4;i++) { if (Acad::eOk == pFace->getVertexAt(i,pt)) { if (arPts.isEmpty()) { arPts.append(pt); } else { if (pt.distanceTo(arPts.last()) > 1.e-3) { AcDbLine* pLn = new AcDbLine(pt,arPts.last()); arLnPtrs.append(pLn); } arPts.append(pt); } } } if (arPts.length() > 2) { AcDbLine* pLn = new AcDbLine(arPts.first(),arPts.last()); arLnPtrs.append(pLn); } double dthick(5.0); AcDbRegion::createFromCurves(arLnPtrs,arRegPtrs); FreeBuffer(0,arLnPtrs); if (!arRegPtrs.isEmpty()) { AcDbRegion* pReg = (AcDbRegion*)arRegPtrs.first(); if (pReg && pSos) { double d; AcGePlane pln; AcGePoint3d pt; AcGeVector3d vt; pReg->getNormal(vt); CoreTools::getRegionInfo(pReg, pt, d, pln); vt.normalize(); vt *= dthick; AcDbX3dSolid *pSo = new AcDbX3dSolid(); pSo->CreateExtrude(pReg, AcDbLine(pt, pt + vt)); pSos->push_back(pSo); } AcDbSurface* pNewSurface = NULL; AcDbSurface::createFrom(pReg,pNewSurface); if (pNewSurface != NULL) { pNewSurface->thicken(dthick,false,pSolid); DELETE_PTR(pNewSurface); } deleteArrayVoidPtrs< AcDbEntity>(arRegPtrs); } } return pSolid; } void DeepFaceToSolid(AcDbBlockReference* pRef,AcDbVoidPtrArray& arGetSolidPtrs) { if (pRef == NULL) return; //提取face; AcDbEntity* pEnt = NULL,*pSubEnt = NULL; AcDbVoidPtrArray arFacePtrs; pRef->explode(arFacePtrs); //face to solid AcDb3dSolid* pFaceSolid = NULL; for (int ii = 0;ii < arFacePtrs.length();ii++) { pEnt = (AcDbEntity*)arFacePtrs.at(ii); AcDbFace* pFace = AcDbFace::cast(pEnt); if (pFace != NULL) { pFaceSolid = FaceToSolid(pFace); if (pFaceSolid != NULL) { arGetSolidPtrs.append(pFaceSolid); } } AcDbPolyFaceMesh* pPFM = AcDbPolyFaceMesh::cast(pEnt); if (pPFM != NULL) { AcDbVoidPtrArray arSubFacePtrs; pPFM->explode(arSubFacePtrs); for(int jj = 0;jj < arSubFacePtrs.length();jj++) { pSubEnt = (AcDbEntity*)arSubFacePtrs.at(jj); pFace = AcDbFace::cast(pSubEnt); if (pFace != NULL) { pFaceSolid = FaceToSolid(pFace); if (pFaceSolid != NULL) { arGetSolidPtrs.append(pFaceSolid); } } delete pSubEnt; } } AcDbBlockReference* pSubRef = AcDbBlockReference::cast(pEnt); if (pSubRef != NULL) { DeepFaceToSolid(pSubRef,arGetSolidPtrs); } delete pEnt; } } int AecDbXOpening::GetDraw3dables(AcDbVoidPtrArray& arEntPtrs,bool bWriteBimInfo/* = false */) const { OpeningData data; GetOpeningData(data); AcDbObjectId idBlk3d; m_mapSpecXData.GetAt(KEY_BLK3DID,idBlk3d); if (idBlk3d.isValid()) { AcGeVector3d vtDir(1,0,0); AcGePoint3d ptPos,ptOn; ptPos = data.ptPos; double dBomEl = data.dBomEl; WallData wData; memset(&wData,0,sizeof(WallData)); AcDbObjectId idWall; m_mapSpecXData.GetAt(KEY_IDCNT1,idWall); AcDbEntity* pEnt = NULL; AecDbXWall* pWall = NULL; if (idWall.isValid()) { if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,idWall,AcDb::kForRead)) { pWall = AecDbXWall::cast(pEnt); if (pWall != NULL) { AcDbCurve* pNaCur = pWall->GetNativeCurve(); if ( pNaCur != NULL) { pNaCur->getClosestPointTo(ptPos,ptOn); pNaCur->getFirstDeriv(ptOn,vtDir); pWall->GetWallData(wData); ptOn.z = wData.dBomEl; ptPos.z = ptOn.z + dBomEl; } } pEnt->close(); } } AcGeScale3d scl3d; scl3d.set(data.dWidth,wData.dThick,data.dHeight); int nDir = 1; m_mapSpecXData.GetAt(PIPE_TDIR,nDir); if (abs(nDir) < 1) nDir = 1; vtDir *= nDir; double dRot = AcGeVector3d::kXAxis.angleTo(vtDir,AcGeVector3d::kZAxis); AcGeScale3d scale = GetBlockToIdentity(idBlk3d); scl3d.sx *= scale.sx; scl3d.sy *= scale.sy; scl3d.sz *= scale.sz; AcDbBlockReference* pRef = new AcDbBlockReference; pRef->setBlockTableRecord(idBlk3d); pRef->setPosition(ptPos); pRef->setRotation(dRot); pRef->setScaleFactors(scl3d); pRef->setLayer(layerId()); arEntPtrs.append(pRef); } return arEntPtrs.length(); } Acad::ErrorStatus AecDbXOpening::Draw3d(AcGiDraw &dc) const { assertReadEnabled(); BOOL bHlrCalc(FALSE); m_mapSpecXData.GetAt(HLR_CALC, bHlrCalc); if (bHlrCalc) { // 如果 bHlrCalc 为真,说明PreprocessForHlr函数要求跳过draw3d函数 // 会在ProcessHlrResult函数设置回来 return Acad::eOk; } if ( dc.IsDragging() ) { //return Acad::eOk; } //图层 AcDbObjectId idLay = dc.GetLayerId(); dc.SetLayer(layerId()); int nCrBk = dc.GetColor(); int nColor = nCrBk; if ( m_mapSpecXData.GetAt(_T("COLOR"),nColor) ) { dc.SetColor(nColor); } if (IsActive()) { nColor = kMagenta; m_mapSpecXData.GetAt(KEY_ACTIVECR,nColor); dc.SetColor(nColor); } if (Has3DBuffer()) { AcDbEntity* pEnt = NULL; const AcDbVoidPtrArray &ar3D = Get3DBuffer(); for (int i = 0;i < ar3D.length();i++) { pEnt = (AcDbEntity*)ar3D.at(i); if ( IsActive() ) { BackupColorIndex(pEnt); pEnt->setColorIndex(nColor); } else { SetBackupColorIndex(pEnt); } dc.DrawEntity(*pEnt); } dc.SetLayer(idLay); dc.SetColor(nCrBk); return Acad::eOk; } OpeningData data; GetOpeningData(data); AcDbObjectId idBlk3d; m_mapSpecXData.GetAt(KEY_BLK3DID,idBlk3d); if (!idBlk3d.isValid()) { idBlk3d = LoadOpeningBlk3d(); } if (idBlk3d.isValid()) { AcGeVector3d vtDir(1,0,0); AcGePoint3d ptPos,ptOn; ptPos = data.ptPos; double dBomEl = data.dBomEl; WallData wData; memset(&wData,0,sizeof(WallData)); AcDbObjectId idWall; m_mapSpecXData.GetAt(KEY_IDCNT1,idWall); AcDbEntity* pEnt = NULL; AcDbEntity* pSubEnt = NULL; AecDbXWall* pWall = NULL; if (idWall.isValid()) { if ( Acad::eOk == acdbOpenAcDbEntity(pEnt,idWall,AcDb::kForRead)) { pWall = AecDbXWall::cast(pEnt); if (pWall != NULL) { AcDbLine* pNaLine = NULL; BOOL bIsVView = FALSE; pWall->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_VVIEW,bIsVView); if (bIsVView) { //1.创建整体Solid AcGePoint3d ptOnRegion; pWall->GetSpecialtyData(AcDb::kForRead)->GetAt(KEY_SECCEN,ptOnRegion); AcDbCurve* pNaCur = pWall->GetNativeCurve(); AcGePoint3d ptSta,ptEnd; pNaCur->getStartPoint(ptSta); pNaCur->getEndPoint(ptEnd); AcGeVector3d vtNormal(AcGeVector3d::kIdentity); pNaCur->getFirstDeriv(ptSta, vtNormal); AcDbRegion* pCloneRegion = pWall->GetSection(); transfromRegion(pCloneRegion, ptOnRegion, vtNormal, ptEnd); AcDbLine* pLn1 = AecDbXWall::GetOrthoProjectOnXY(pCloneRegion); if (pLn1 != NULL) { AcGePoint3d ptMid,ptMid2; GetMidPoint(pNaCur,ptMid); ptMid.z = 0.0; pLn1->getClosestPointTo(ptMid,ptMid2); AcGeVector3d vtM = ptMid - ptMid2; AcGeMatrix3d xM;xM.setToTranslation(vtM); pLn1->transformBy(vtM); pNaLine = pLn1; } delete pCloneRegion; } AcDbCurve* pNaCur = pWall->GetNativeCurve(); if (pNaLine != NULL) { pNaLine->getClosestPointTo(ptPos,ptOn); pNaLine->getFirstDeriv(ptOn,vtDir); pWall->GetWallData(wData); ptOn.z = wData.dBomEl; ptPos.z = ptOn.z + dBomEl; } else { if ( pNaCur != NULL) { pNaCur->getClosestPointTo(ptPos,ptOn); pNaCur->getFirstDeriv(ptOn,vtDir); pWall->GetWallData(wData); ptOn.z = wData.dBomEl; ptPos.z = ptOn.z + dBomEl; } } } pEnt->close(); } } AcGeScale3d scl3d; scl3d.set(data.dWidth,wData.dThick,data.dHeight); int nDir = 1; m_mapSpecXData.GetAt(PIPE_TDIR,nDir); if (abs(nDir) < 1) nDir = 1; vtDir *= nDir; double dRot = AcGeVector3d::kXAxis.angleTo(vtDir,AcGeVector3d::kZAxis); AcGeScale3d scale = GetBlockToIdentity(idBlk3d); scl3d.sx *= scale.sx; scl3d.sy *= scale.sy; scl3d.sz *= scale.sz; //绘制 dc.DrawBlock(idBlk3d,ptPos,scl3d,dRot,FALSE); //块引用分解到体 AcDbBlockReference* pRef = new AcDbBlockReference; pRef->setTransparency(transparency()); pRef->setBlockTableRecord(idBlk3d); pRef->setPosition(ptPos); pRef->setRotation(dRot); pRef->setScaleFactors(scl3d); pRef->setLayer(layerId()); if (data.nType == 1) pRef->setColorIndex(4); pRef->setTransparency(transparency()); Add3DBuffer(pRef); } return Acad::eOk; } Acad::ErrorStatus AecDbXOpening::dwgInFields(AcDbDwgFiler* pFiler) { AssertWriteEnabled(); //----- Read parent class information first. Acad::ErrorStatus es = Acad::eOk; if ( !pFiler->isKindOf(CMFCDbDwgFiler::desc())) { es = AecDbEntityBase::dwgInFields (pFiler) ; if ( es != Acad::eOk ) return (es) ; } //----- Object version number needs to be read first Adesk::UInt32 version =0 ; if ( (es = pFiler->readUInt32 (&version)) != Acad::eOk ) return (es) ; if ( version > AecDbXOpening::kCurrentVersionNumber ) return (Acad::eMakeMeProxy) ; //2D m_mapSpecXData.dwgInFields(pFiler); return (pFiler->filerStatus ()); } Acad::ErrorStatus AecDbXOpening::dwgOutFields(AcDbDwgFiler* pFiler) const { assertReadEnabled(); //----- Save parent class information first. Acad::ErrorStatus es = Acad::eOk; if ( !pFiler->isKindOf(CMFCDbDwgFiler::desc())) { es = AecDbEntityBase::dwgOutFields (pFiler) ; if ( es != Acad::eOk ) return (es) ; } //----- Object version number needs to be saved first if ( (es =pFiler->writeUInt32 (AecDbXOpening::kCurrentVersionNumber)) != Acad::eOk ) return (es) ; //2D m_mapSpecXData.dwgOutFields(pFiler); return (pFiler->filerStatus ()); } Acad::ErrorStatus AecDbXOpening::dxfInFields(AcDbDxfFiler* pFiler) { return Acad::eOk; } Acad::ErrorStatus AecDbXOpening::dxfOutFields(AcDbDxfFiler* pFiler) const { return Acad::eOk; } Acad::ErrorStatus AecDbXOpening::subErase(Adesk::Boolean erasing) { if (erasing) { PreRefreshWallDraw();//修复墙体 } else { RefreshWallDraw();// } return AcDbEntity::subErase(erasing); } AecDbObjXDataMap* AecDbXOpening::GetSpecialtyData(AcDb::OpenMode bMode/* = AcDb::kForWrite*/) { switch(bMode) { case AcDb::kForRead: { assertReadEnabled(); break; } case AcDb::kForWrite: { if (!isWriteEnabled()) { upgradeOpen(); } assertWriteEnabled(); break; } case AcDb::kForNotify: { assertReadEnabled(); } default: break; } return &m_mapSpecXData; } const AecDbObjXDataMap* AecDbXOpening::GetSpecialtyData() const { assertReadEnabled(); return &m_mapSpecXData; } //剖切符合draw2d符号 bool AecDbXOpening::SectionAsDraw2d(AcGePlane& plan,AcDbVoidPtrArray &arRegionPtrs) const { AcGeVector3d vtZ = plan.normal(); AcDbEntity *pEnt2d = NULL, *pEnt3d = NULL; const AcDbVoidPtrArray &arDraw2d = Get2DBuffer(); for (int i = 0; i < arDraw2d.length(); i++) { pEnt2d = (AcDbEntity *)arDraw2d.at(i); AcDbBlockReference *pRef2d = AcDbBlockReference::cast(pEnt2d); if (pRef2d != NULL) { double dRot = pRef2d->rotation(); AcGeVector3d vtDir = AcGeVector3d::kXAxis; vtDir.rotateBy(dRot, AcGeVector3d::kZAxis); if (vtDir.isParallelTo(vtZ)) { AecDbXOpening *pFit = (AecDbXOpening *)clone(); if (pFit != NULL) { AcGiViewDraw dc(NULL, NULL); pFit->Draw3d(dc); AcDbVoidPtrArray arDraw3d; pFit->GetDraw3dables(arDraw3d, false); //剖切符号,然后获取3D的位置信息 for (int j = 0; j < arDraw3d.length(); j++) { pEnt3d = (AcDbEntity *)arDraw3d.at(j); AcDbBlockReference *pRef3d = AcDbBlockReference::cast(pEnt3d); if (pRef3d != NULL) { //scl3d.set(data.dWidth, wData.dThick, data.dHeight); AcGeScale3d scl3d = pRef3d->scaleFactors(); AcGePoint3d ptPos = pRef3d->position(); AcGeScale3d scale = GetBlockToIdentity(pRef3d->blockTableRecord()); scl3d.sx /= scale.sx; scl3d.sy /= scale.sy; scl3d.sz /= scale.sz; AcGeMatrix3d xform; xform.setToPlaneToWorld(plan); xform.invert(); ptPos.transformBy(xform); ptPos.z = 0.0; //根据 剖面门窗.dwg 库 特殊符号的调整位置 ptPos.x -= scl3d.sy * 0.5; //vtDir.transformBy(xform); AcDbObjectId idOpening = LoadOpeningSectionDrawBlk2d(); if (!idOpening.isValid()) { delete pFit; return false; } scale = GetBlockToIdentity(idOpening); AcDbBlockReference *pRefNew = new AcDbBlockReference; pRefNew->setBlockTableRecord(idOpening); pRefNew->setLayer(pRef2d->layerId()); pRefNew->setPosition(ptPos); //剖切门窗总是Y方向放置,所以 scl3d.sy,scl3d.sz AcGeScale3d scale2d; scale2d.set(scl3d.sy,scl3d.sz,1.0); int nType = 0; m_mapSpecXData.GetAt(KEY_TYPE, nType); scale2d.sx *= scale.sx; scale2d.sy *= scale.sy; pRefNew->setScaleFactors(scale2d); //dRot = AcGeVector3d::kXAxis.angleTo(vtDir, AcGeVector3d::kZAxis); //根据 剖面门窗.dwg 库 dRot = 0.0 dRot = 0.0;//特殊符号原始角度 pRefNew->setRotation(dRot); arRegionPtrs.append(pRefNew); delete pFit; return true; } } delete pFit; } break; } if (vtDir.isPerpendicularTo(vtZ)) { //且剖切面平行 XY 面 取原来符号 if ( vtZ.isParallelTo(AcGeVector3d::kZAxis) ) { AecDbXOpening *pFit = (AecDbXOpening *)clone(); if (pFit != NULL) { AcGeMatrix3d xform; xform.setToPlaneToWorld(plan); xform.invert(); pFit->transformBy(xform); AcGiViewDraw dc(NULL, NULL); pFit->Draw2d(dc); arRegionPtrs.append(pFit->Get2DBuffer()); delete pFit; return true; } } } } } return false; } int AecDbXOpening::GetSectionDraw(const AcGePoint3d& ptFr,const AcGePoint3d& ptTo,const AcGeVector3d& vtViewDir,const AcGeVector3d& vtTo, AcDbVoidPtrArray& arRegionPtrs) const { assertReadEnabled(); AcDbObjectId idLayer = layerId(); AcGeVector3d vtLn = ptTo - ptFr; AcGeVector3d vtNorm = vtLn.crossProduct(vtViewDir); AcGePlane plan; plan.set(ptFr,vtNorm); AcGeMatrix3d xform; xform.setToPlaneToWorld(plan); xform.invert(); //如果是符合剖切符号 if (SectionAsDraw2d(plan,arRegionPtrs) ) { return arRegionPtrs.length(); } AecDbXOpening* pFit = (AecDbXOpening*)clone(); if (pFit != NULL) { AcGiViewDraw dc(NULL, NULL); pFit->Draw3d(dc); AcDbVoidPtrArray arSubPtrs; pFit->GetDraw3dables(arSubPtrs,false); AcDbEntity* pSubEnt = NULL; if (arSubPtrs.length() >= 1) { pSubEnt = (AcDbEntity*)arSubPtrs.first();//就一个 if (pSubEnt != NULL) { AcDbVoidPtrArray arEntPtrs; OrthoProjectedEntity(pSubEnt, plan, xform, arEntPtrs); CString sName, sNameUq; m_mapSpecXData.GetAt(KEY_BLK2D, sName); MakeBlockRefSet(arEntPtrs, layerId(), Adesk::kTrue,sName); arRegionPtrs.append(arEntPtrs); } } delete pFit; } return arRegionPtrs.length(); } namespace { AcDbPolyFaceMesh* DBRegion2PolyFace(AcDbRegion *pReg) { if (!pReg) return NULL; AcDbFaceterSettings faceter = { .0, .0, krAutomatic, .0, false, false }; AcGePoint3dArray vertexArray; AcArray faceArray; AcGiFaceData *faceData(NULL); if (acdbGetObjectMesh(pReg, &faceter, vertexArray, faceArray, faceData) == Acad::eOk) { if (faceData) { delete[] faceData->trueColors(); delete[] faceData->materials(); delete faceData; } AcDbPolyFaceMesh *pMesh = new AcDbPolyFaceMesh(); int idx1, idx2, idx3, idx0; for (int i(0); i < vertexArray.length(); ++i) pMesh->appendVertex(new AcDbPolyFaceMeshVertex(vertexArray[i])); for (int i(0); i < faceArray.length();) { if (faceArray[i] == 3) { idx0 = faceArray[i + 1] +1; idx1 = faceArray[i + 2] +1; idx2 = faceArray[i + 3] +1; idx3 = 0; } else if (faceArray[i] == 4) { idx0 = faceArray[i + 1] +1; idx1 = faceArray[i + 2] +1; idx2 = faceArray[i + 3] +1; idx3 = faceArray[i + 4] +1; } pMesh->appendFaceRecord(new AcDbFaceRecord(idx0, idx1, idx2, idx3)); i += faceArray[i] + 1; } return pMesh; } return NULL; } AcDbPolyFaceMesh* DbFace2PolyFace(AcDbFace *pFace) { if (!pFace) return NULL; AcGePoint3d pt0, pt1, pt2, pt3; pFace->getVertexAt(0, pt0); pFace->getVertexAt(1, pt1); pFace->getVertexAt(2, pt2); pFace->getVertexAt(3, pt3); AcDbPolyFaceMesh *pMesh = new AcDbPolyFaceMesh(); pMesh->appendVertex(new AcDbPolyFaceMeshVertex(pt0)); pMesh->appendVertex(new AcDbPolyFaceMeshVertex(pt1)); pMesh->appendVertex(new AcDbPolyFaceMeshVertex(pt2)); pMesh->appendVertex(new AcDbPolyFaceMeshVertex(pt3)); if (pt2.distanceTo(pt3) < 1e-6) // 三点 { pMesh->appendFaceRecord(new AcDbFaceRecord(1, 2, 3, 0)); } else // 四点 { pMesh->appendFaceRecord(new AcDbFaceRecord(1, 2, 3, 4)); } return pMesh; } void ExplodeEnt2Face(AcDbEntity *p3DEnt, AcDbVoidPtrArray &arCurPtrs) { AcDbVoidPtrArray arEntPtrs; if (!p3DEnt) return; if (AcDbFace::cast(p3DEnt)) { arCurPtrs.append((AcDbFace*)p3DEnt->clone()); return; } p3DEnt->explode(arEntPtrs); for (int k = 0; k < arEntPtrs.length(); k++) { AcDbEntity *pEnt = (AcDbEntity *)((AcDbEntity *)arEntPtrs.at(k))->clone(); AcDbFace *pFace = AcDbFace::cast(pEnt); if (pFace != NULL) { arCurPtrs.append(pFace); } else { ExplodeEnt2Face(pEnt, arCurPtrs); DELETE_PTR(pEnt); } } deleteArrayVoidPtrs< AcDbEntity>(arEntPtrs); } void _explode(AcDbBlockReference *pRef , AcDbVoidPtrArray &arPtrs , const AcGeMatrix3d &matParent) { OPENOBJ_BEGIN(pRef->blockTableRecord(), AcDb::kForRead, AcDbBlockTableRecord, pRec) if (pRec) { AcString name; pRec->getName(name); if (false) { pRef->transformBy(matParent); CoreTools::CloneAndAddToModelSpace(pRef); return; } AcDbBlockTableRecordIterator *pIter(NULL); if (Acad::eOk == pRec->newIterator(pIter)) { AcDbEntity *pEnt(NULL); for (pIter->start(); !pIter->done(); pIter->step()) { pIter->getEntity(pEnt, AcDb::kForRead); if (!pEnt) continue; AcDbBlockReference *p = AcDbBlockReference::cast(pEnt); if (p) { _explode(p, arPtrs, pRef->blockTransform() * matParent); } else { AcDbEntity *pClone = (AcDbEntity *)pEnt->clone(); if (pClone->transformBy(pRef->blockTransform() * matParent) != Acad::eOk) { // 处理一下不支持非均匀缩放的实体 AcDbPolyFaceMesh *pMesh(NULL); AcDbRegion *pReg = AcDbRegion::cast(pClone); if (pReg) pMesh = DBRegion2PolyFace(pReg); AcDbFace *pFace = AcDbFace::cast(pClone); if (pFace) pMesh = DbFace2PolyFace(pFace); if (pMesh) { pMesh->transformBy(pRef->blockTransform() * matParent); arPtrs.append(pMesh); } } else arPtrs.append(pClone); } pEnt->close(); } DELETE_PTR(pIter); pIter = NULL; } } OPENOBJ_END() } } SHJson::WValue & AecDbXOpening::ToJson(bool bExprotGeo) const { using namespace SHJson; WValue &v = AecDbEntityBase::ToJson(bExprotGeo); if (bExprotGeo) { if (!Has3DBuffer()) { AcGiViewDraw dc; Draw3d(dc); } AcDbVoidPtrArray arptrs = Get3DBuffer(), ents, faces; for (int i(0); i < arptrs.length(); ++i) { ents.removeAll(); AcDbEntity *pEnt = (AcDbEntity *)arptrs[i]; AcDbBlockReference *pRef = AcDbBlockReference::cast(pEnt); if (!pRef) continue; pRef = (AcDbBlockReference *)pRef->clone(); pRef->setPosition(AcGePoint3d::kOrigin); pRef->setRotation(.0); _explode(pRef, ents, AcGeMatrix3d::kIdentity); for (int i(0); i < ents.length(); ++i) ExplodeEnt2Face((AcDbEntity*)ents[i], faces); deleteArrayVoidPtrs< AcDbEntity>(ents); DELETE_PTR(pRef); } GEO2JSON::tessellations tess; for (int i(0); i < faces.length(); ++i) { AcDbFace *pFace((AcDbFace *)faces[i]); if (!pFace) continue; GEO2JSON::tools::fromFace(tess, pFace); } deleteArrayVoidPtrs< AcDbEntity>(faces); WValue ar; ar.SetArray(); for (size_t i(0); i < tess.size(); ++i) { WValue &x = tess[i].ToJson(); pushBack(ar, x); } addMember(v, _T("__tessellations__"), ar); } OpeningData data; ::memset(&data, 0, sizeof(OpeningData)); GetOpeningData(data); /*int nType; //窗:2 门 1 int nFlag; //特殊标记 double dWidth; //门窗宽度 double dHeight; //门窗高度 double dBomEl; //相对墙体底部标高 AcGePoint3d ptPos; //位置,Z是真实标高 TCHAR szBlockName2d[MAX_PATH];//本地文件名2d TCHAR szBlockName3d[MAX_PATH];//本地文件名3d TCHAR szName[MAX_PATH]; //名称 TCHAR szSpec[MAX_PATH]; //附属信息 TCHAR szNo[65];//编号 TCHAR szFactory[MAX_PATH];//厂家*/ WValue open; addMember(open, _T("__nType__"), data.nType); addMember(open, _T("__nFlag__"), data.nFlag); addMember(open, _T("__dWidth__"), data.dWidth); addMember(open, _T("__dHeight__"), data.dHeight); addMember(open, _T("__dBomEl__"), data.dBomEl); addMember(open, _T("__ptPos__"), GEO2JSON::point(data.ptPos).ToJson()); addMember(open, _T("__szBlockName2d__"), data.szBlockName2d); addMember(open, _T("__szBlockName3d__"), data.szBlockName3d); addMember(open, _T("__szName__"), data.szName); addMember(open, _T("__szSpec__"), data.szSpec); addMember(open, _T("__szNo__"), data.szNo); addMember(open, _T("__szFactory__"), data.szFactory); addMember(v, _T("_open_data_"), open); return v; } bool AecDbXOpening::ByJson(const SHJson::WValue & v) { return AecDbEntityBase::ByJson(v); } #include "HlrCutOption.h" void AecDbXOpening::ProcessHlrResult(const AcArray &ar , const std::map> &preAr , AcArray &output) const { const AecDbObjXDataMap *pMap(&m_mapSpecXData); BOOL b3D(0); const_cast(pMap)->GetAt(HLR_CALC, b3D); const_cast(pMap)->SetAt(HLR_CALC, FALSE); // 如果b3D==1981,说明是垂直剖切的结果 // 否则是水平剖切的结果 bool bHoriz(b3D != 1981); if (ar.isEmpty() && preAr.empty()) return; // preAr 内部可能是两种数据 // 1. 水平剖切的数据 // 2. 垂直剖切(3d下的 blockrefence) AcArray _ar(ar); std::map> _preAr(preAr); bool bFullMask(true); if (!preAr.empty() && HlrCutOption::getHlrSTYLE2D_OPEN()) { _ar.removeAll(); // 把 preAr 中的 region 生成的结果挑出来,不显示 std::map>::iterator it(_preAr.begin()); for (; it != _preAr.end(); ++it) { if (AcDbRegion::cast(it->first)) { _preAr.erase(it); bFullMask = false; } } } // 如果是水平剖切,并且没有region,说明实体完全被遮挡 if (bHoriz && bFullMask) return; HlrCutOption::ProcessHlrResult(this , FALSE , .0 , HlrCutOption::getHlrBLK_OPEN() , _ar , _preAr , output); } // AecDbXOpening 类的 水平、垂直剖切,都走PreprocessForHlr()函数 void AecDbXOpening::PreprocessForHlr(const AcGePoint3d &ptPlnO , const AcGeVector3d &vtPlnN , AcArray &ar) const { // 不是水平剖切时,需要特殊处理3d,hlr引擎不能看到门窗类里面的blockrefrence // 所以在这里把 blockrefrence 提取出来 if (!vtPlnN.isParallelTo(AcGeVector3d::kZAxis)) { // 门窗需要特殊处理,门窗的draw3d 内部绘制的是 blockrefrence, if (!Has3DBuffer()) { AcGiViewDraw dc; Draw3d(dc); } const AcDbVoidPtrArray ar3ds(Get3DBuffer()); if (ar3ds.isEmpty()) return; for (int i(0); i < ar3ds.length(); ++i) ar.append((AcDbEntity *)((AcDbEntity *)ar3ds[i])->clone()); const AecDbObjXDataMap *pMap(&m_mapSpecXData); const_cast(pMap)->SetAt(HLR_CALC, 1981); return; } // 剩下的情况就是时水平剖切 if (!HlrCutOption::getHlrSTYLE2D_VALVE()) return; const AcDbVoidPtrArray ar2ds = Get2DBuffer(); if (ar2ds.isEmpty()) return; OpeningData data; ::memset(&data, 0, sizeof(OpeningData)); GetOpeningData(data); AcDbObjectId idWall; idWall.setFromOldId(data.idWall); AcDbObjectPointer wall(idWall, AcDb::kForRead); WALLDATA wd; ::memset(&wd, 0, sizeof(WALLDATA)); wall->GetWallData(wd); double dMax(.0), dMin(.0); if (wall.openStatus() != Acad::eOk) return; if (data.nType == 2) // 门 { dMax = wd.dBomEl + data.dHeight; dMin = wd.dBomEl; } if (data.nType == 1) // 窗 { dMax = wd.dBomEl + data.dBomEl + data.dHeight; dMin = wd.dBomEl + data.dBomEl; } if (!HlrCutOption::isWithinHorizSection(dMax, dMin, ptPlnO, vtPlnN)) return; double dElev(dMax); if (ptPlnO.z < dMax) dElev = ptPlnO.z; AcGeMatrix3d mat; mat.setTranslation(AcGeVector3d::kZAxis * (dElev - data.ptPos.z)); AcGeVector3d vtDir(wall->EndPoint() - wall->StartPoint()); AcGeVector3d vtX(vtDir); vtX.normalize(); AcGeVector3d vtY(vtX); vtY.rotateBy(PI * .5, AcGeVector3d::kZAxis); vtY.normalize(); vtX *= data.dWidth * .5; vtY *= data.dThick * .5; AcGePoint3d pt0(data.ptPos); pt0 += vtX; pt0 += vtY; AcGePoint3d pt1(data.ptPos); pt1 += vtX; pt1 -= vtY; AcGePoint3d pt2(data.ptPos); pt2 -= vtX; pt2 -= vtY; AcGePoint3d pt3(data.ptPos); pt3 -= vtX; pt3 += vtY; AcDbVoidPtrArray arLines; arLines.append(new AcDbLine(pt0, pt1)); arLines.append(new AcDbLine(pt1, pt2)); arLines.append(new AcDbLine(pt2, pt3)); arLines.append(new AcDbLine(pt3, pt0)); AcDbRegion *pReg = CoreTools::createRegion(arLines); deleteArrayVoidPtrs(arLines); if (pReg) { pReg->transformBy(mat); ar.append(pReg); } for (int i(0); i < ar2ds.length(); ++i) { AcDbEntity *pEnt((AcDbEntity *)((AcDbEntity *)ar2ds[i])->clone()); pEnt->transformBy(mat); ar.append(pEnt); } const AecDbObjXDataMap *pMap(&m_mapSpecXData); const_cast(pMap)->SetAt(HLR_CALC, TRUE); } namespace { typedef std::map RECMAP; // std::map // 2dRecName-3dRecDWgName void get2dRecList(const bool &bWin, RECMAP &recMapping) { CString sPath, sRoot; KTSetting::GetKTPsPath(sPath); sRoot = sPath + _T("Support\\Cells"); if (bWin) sPath = sRoot + _T("\\WindowDb.txt"); else sPath = sRoot + _T("\\DoorDb.txt"); int nIndex = -1; CStdioFile file; if (file.Open(sPath, CFile::modeRead | CFile::typeText)) { CString sText , s2DRecDwgName, s3DRecDwgPath , s2DRecName, s3DRecName , s2DRecDwgPath; while (file.ReadString(sText)) { if (sText.FindOneOf(_T("//")) != -1) { continue; } nIndex = sText.Find(_T(';')); if (nIndex != -1) { CStringArray arFields; CoreTools::SplitStrintToArray(sText, arFields, _T(';')); if (arFields.GetSize() >= 3) { s2DRecDwgName = arFields.GetAt(0); s2DRecName = arFields.GetAt(1); s2DRecDwgPath = sRoot + _T("\\") + s2DRecDwgName; s3DRecName = arFields.GetAt(2); if (arFields.GetCount() > 3) s3DRecDwgPath = sRoot + _T("\\") + arFields.GetAt(3); else s3DRecDwgPath = sRoot + _T("\\") + s3DRecName + _T(".dwg"); recMapping.insert(std::make_pair(s2DRecName, s3DRecDwgPath)); } } } file.Close(); } } void get3dRecList(const bool &bWin, std::vector &list, LPCTSTR pszPath) { AcDbDatabase *pDb(new AcDbDatabase(false)); Acad::ErrorStatus es; if (Acad::eOk != (es = pDb->readDwgFile(pszPath))) { delete pDb; pDb = NULL; return; } if (pDb != NULL) { std::vector vec; CoreTools::enumBlockByDWG(pDb, vec); CString sName; for (size_t i(0); i < vec.size(); ++i) { sName = vec[i]; if (sName.CompareNoCase(_T("*Model_Space")) == 0 || sName.CompareNoCase(_T("*Paper_Space")) == 0 || sName.CompareNoCase(_T("_ArchTick")) == 0) { } else { list.push_back(sName); } } } } } bool AecDbXOpening::GetProperties(SimpleProperty::PropertySetByIndex &properties) const { assertReadEnabled(); AecDbEntityBase::GetProperties(properties); CoreTools::setLayerPorperty(properties); CoreTools::setSubSystemPorperty(properties); OpeningData data; memset(&data, 0, sizeof(OpeningData)); GetOpeningData(data); if (data.nType == 1)//窗 { SimpleProperty::makeAndInsert(properties, _T("类型"), _T("窗"), false); SimpleProperty::makeAndInsert(properties, _T("窗高"), data.dHeight, true); SimpleProperty::makeAndInsert(properties, _T("窗宽"), data.dWidth, true); SimpleProperty::makeAndInsert(properties, _T("窗台高"), data.dBomEl, true); } else if (data.nType == 2) // 门 { SimpleProperty::makeAndInsert(properties, _T("类型"), _T("门"), false); SimpleProperty::makeAndInsert(properties, _T("门高"), data.dHeight, true); SimpleProperty::makeAndInsert(properties, _T("门宽"), data.dWidth, true); SimpleProperty::makeAndInsert(properties, _T("门槛高"), data.dBomEl, true); } SimpleProperty::makeAndInsert(properties, _T("材质"), data.szSpec, true); SimpleProperty::makeAndInsert(properties, _T("生产厂家"), data.szFactory, true); std::vector recs3d; RECMAP recmap; get2dRecList(data.nType == 1, recmap); std::vector recs2d; if (!recmap.empty()) { for (RECMAP::const_iterator it(recmap.begin()); it != recmap.end(); ++it) recs2d.push_back(it->first); } if (!recs2d.empty()) SimpleProperty::makeAndInsert(properties , _T("二维样式名称") , data.szBlockName2d , true , recs2d); else SimpleProperty::makeAndInsert(properties , _T("二维样式名称") , data.szBlockName2d , false); RECMAP::const_iterator it = recmap.find(data.szBlockName2d); if (it != recmap.end()) get3dRecList(data.nType == 1, recs3d, it->second); if (!recs3d.empty()) SimpleProperty::makeAndInsert(properties , _T("三维样式名称") , data.szBlockName3d , true , recs3d); else SimpleProperty::makeAndInsert(properties , _T("三维样式名称") , data.szBlockName3d , false); return true; } bool AecDbXOpening::SetProperties(SimpleProperty::PropertySetByName & properties) { if (properties.m_set.empty()) return false; AecDbEntityBase::SetProperties(properties); OpeningData data; memset(&data, 0, sizeof(OpeningData)); GetOpeningData(data); properties.findAndSet(_T("窗高"), data.dHeight); properties.findAndSet(_T("窗宽"), data.dWidth); properties.findAndSet(_T("窗台高"), data.dBomEl); properties.findAndSet(_T("门高"), data.dHeight); properties.findAndSet(_T("门宽"), data.dWidth); properties.findAndSet(_T("门槛高"), data.dBomEl); properties.findAndSet(_T("材质"), data.szSpec); properties.findAndSet(_T("生产厂家"), data.szFactory); CString sVal(_T("")); if (properties.findAndSet(_T("二维样式名称"), sVal)) { _tcscpy_s(data.szBlockName2d, sVal); _tcscpy_s(data.szName, sVal); } properties.findAndSet(_T("三维样式名称"), data.szBlockName3d); AcDbObjectId idWall; m_mapSpecXData.GetAt(KEY_IDCNT1,idWall); SetOpeningData(data, idWall); return false; } Acad::ErrorStatus AecDbXOpening::subWblockClone(AcRxObject * pOwnerObject , AcDbObject *& pClonedObject , AcDbIdMapping & idMap , Adesk::Boolean isPrimary) const { // 如果已经克隆过了,就直接返回,避免重复克隆 AcDbIdPair idPairOpening(id(), AcDbObjectId::kNull, false, isPrimary ? true : false); if (idMap.compute(idPairOpening)) return Acad::eOk; Acad::ErrorStatus es = AecDbEntityBase::subWblockClone(pOwnerObject, pClonedObject, idMap, isPrimary); if (es != Acad::eOk) return es; if (!pClonedObject) return es; AecDbXOpening *pOpening = AecDbXOpening::cast(pClonedObject); if (pOpening) pOpening->SetAt(KEY_IDCNT1, AcDbObjectId::kNull); return es; } Acad::ErrorStatus AecDbXOpening::subDeepClone(AcDbObject * pOwnerObject , AcDbObject *& pClonedObject , AcDbIdMapping & idMap , Adesk::Boolean isPrimary) const { // 如果已经克隆过了,就直接返回,避免重复克隆 AcDbIdPair idPairOpening(id(), AcDbObjectId::kNull, false, isPrimary ? true : false); if (idMap.compute(idPairOpening)) return Acad::eOk; Acad::ErrorStatus es = AecDbEntityBase::subDeepClone(pOwnerObject, pClonedObject, idMap, isPrimary); if (es != Acad::eOk) return es; if (!pClonedObject) return es; AecDbXOpening *pOpening = AecDbXOpening::cast(pClonedObject); if (pOpening) pOpening->SetAt(KEY_IDCNT1, AcDbObjectId::kNull); return es; }