#include "stdafx.h" #include "DlgBase.h" #include "AecDbEarthWorm.h" #include "KTCADUtilityEx.h" #include "UITools.h" #ifndef EW_ROOMSLAB #define EW_ROOMSLAB _T("ROOMSLAB") #endif namespace { void FreeBuffer(AcDbVoidPtrArray& arTextPtrs) { AcDbEntity* pEnt = NULL; while (arTextPtrs.length() > 0) { pEnt = (AcDbEntity*)arTextPtrs.first(); arTextPtrs.removeFirst(); DELETE_PTR(pEnt); } } } ////////////////////////////////////////////////////////////////////////// IMPLEMENT_DYNAMIC(CBaseDialog, CDialog) BEGIN_MESSAGE_MAP(CBaseDialog, CDialog) ON_MESSAGE(WM_VIEW_LBUTTONDOWN, &CBaseDialog::OnViewLButtonDown) ON_BN_CLICKED(IDOK, &CBaseDialog::OnOK) END_MESSAGE_MAP() CBaseDialog::CBaseDialog(UINT IDD, LPCTSTR pszTag, UINT GSViewID, CWnd *pParent) : CDialog(IDD, pParent) , m_bInplaceEdit(false) , m_idxRoom(-1) , m_idGSView(GSViewID) , m_sTag(pszTag) , m_pRectCell(NULL) , m_roomTypes(0) { if (m_idGSView != -1) { m_pRectCell = new AcDbPolyline; m_pRectCell->addVertexAt(0, AcGePoint2d::kOrigin); m_pRectCell->addVertexAt(1, AcGePoint2d(1, 0)); m_pRectCell->addVertexAt(1, AcGePoint2d(1, 1)); m_pRectCell->addVertexAt(1, AcGePoint2d(0, 1)); m_pRectCell->setColorIndex(6); m_pRectCell->setClosed(Adesk::kTrue); m_pRectCell->setConstantWidth(0.1); } ::memset(&m_data, 0, sizeof(EWFnctNode)); m_dChamferInter = 100.0f; } CBaseDialog::~CBaseDialog() { } bool CBaseDialog::GetFnctNode(EWFnctNode *nodePtr) { if (!nodePtr) return false; ::memcpy(nodePtr, &m_data, sizeof(EWFnctNode)); return true; } bool CBaseDialog::SetFnctNode(EWFnctNode *nodePtr) { if (!nodePtr) return false; ::memcpy(&m_data, nodePtr, sizeof(EWFnctNode)); return true; } bool CBaseDialog::RoomHasSplitRoom(int nRoomIndex) { //m_mapAddtion //sKey.Format(_T("%d-%d-ROOMSLAB"), nRoomIndex, nPos); int nPos = -1,nRoomIndex2 = -1; CString sKey,sVal; for (POSITION ps = m_mapAddtion.GetStartPosition();ps != NULL;) { m_mapAddtion.GetNextAssoc(ps,sKey,sVal); if (sKey.Find(EW_ROOMSLAB) != -1) { nPos = sKey.Find(_T('-')); if (nPos != -1) { nRoomIndex2 = _ttoi(sKey.Mid(0,nPos)); if (nRoomIndex2 == nRoomIndex) { return true; } } } } return false; } void CBaseDialog::ShowEarthWorm() { if (m_idGSView == -1) return; m_arDrawBuffer.removeAll(); m_wndViewCtrl.clearAll(); m_wndViewCtrl.init(true); m_wndViewCtrl.SetOrbitFlag(OBF_PAN | OBF_ZOOM | OBF_COTE); AecDbEarthWorm worm; worm.SetCrossSectionScr(m_sCrossSectionScr); worm.SetChamferInter(m_dChamferInter); ESection eType = eRect; AcGePoint2dArray arDatas; eType = worm.ExtractEarthWormScr(arDatas); AcGeLineSeg3d ln; AcGePoint3d pt2(1000.0, 0, 0); ln.set(AcGePoint3d::kOrigin, pt2); AcDbRegion* pEWRegion = worm.CreateSectionRegion(ln, eType, arDatas); if (!pEWRegion) return; AcDbEntity* pEnt = NULL; AcDbExtents exts; pEWRegion->getGeomExtents(exts); m_wndViewCtrl.InitFromCurrentView2D(exts,true); m_wndViewCtrl.Add(pEWRegion); m_arDrawBuffer.append(pEWRegion); AcDbVoidPtrArray arr; int rooms = worm.CreateSectionRoomRegion(ln, eType, arDatas, arr); Acad::ErrorStatus es; AcDbRegion* pRegIn = NULL; AcDbVoidPtrArray arr2; worm.CreateSectionRoomAddition(ln,eType,arr2); for (int i = 0; i < arr2.length(); i++) { pEnt = (AcDbEntity*)arr2.at(i); pRegIn = AcDbRegion::cast(pEnt); if (pRegIn != NULL) { es = pEWRegion->booleanOper(AcDb::kBoolUnite,pRegIn); } else { m_wndViewCtrl.Add(pEnt); m_arDrawBuffer.append(pEnt); } } AcDbRegion* pReg = NULL; AcGePoint3d ptIns(AcGePoint3d::kOrigin); AcDbText *pText(NULL); if (m_roomTypes.size() < arr.length()) { m_wndViewCtrl.view()->invalidate(); m_wndViewCtrl.Invalidate(); m_wndViewCtrl.RedrawWindow(); return; } CString sRoomName; AcDbExtents exSubRoom; CStringArray arNames; for (int i = 0; i < arr.length(); i++)//主舱室region,i舱室索引 { pEnt = (AcDbEntity*)arr.at(i); pReg = AcDbRegion::cast(pEnt); if (pReg != NULL) { AcDbExtents ext; pReg->getGeomExtents(ext); sRoomName = m_roomTypes[i]; { exSubRoom = ext; //判断主舱室如果有分舱,则名称置为空格 if (RoomHasSplitRoom(i)) { sRoomName = _T(" "); } //中点 ptIns.x = (exSubRoom.maxPoint().x + exSubRoom.minPoint().x) * 0.5; ptIns.y = (exSubRoom.maxPoint().y + exSubRoom.minPoint().y) * 0.5; if (m_mapNameToDbText.Lookup(sRoomName,(void*&)pText)) { pText->setTextString(sRoomName); } else { pText = new AcDbText(ptIns,sRoomName,acdbCurDwg()->textstyle(),0.15,0.0); pText->setHeight(.15); pText->setColorIndex(1); pText->setTextStyle(acdbCurDwg()->textstyle()); //pText->setHorizontalMode(AcDb::kTextAlign); pText->setHorizontalMode(AcDb::kTextLeft); m_mapNameToDbText.SetAt(sRoomName,pText); } if (pText != NULL) { pText->setAlignmentPoint(ptIns); pText->setPosition(ptIns); m_wndViewCtrl.Add(pText); m_arDrawBuffer.append(pText); } } } } m_wndViewCtrl.view()->invalidate(); m_wndViewCtrl.Invalidate(); m_wndViewCtrl.RedrawWindow(); } void CBaseDialog::SetCrossSectionScr(const AcDbObjectId &id) { OPENOBJ_BEGIN(id, AcDb::kForRead, AecDbEarthWorm, pEw) if (pEw) { pEw->GetCrossSectionScr(m_sCrossSectionScr); } OPENOBJ_END() } bool CBaseDialog::GetCrossSectionScr(CString& sCrossSectionScr) { sCrossSectionScr = m_sCrossSectionScr; if (sCrossSectionScr.IsEmpty()) return false; return true; } AecDbObjXDataMap* CBaseDialog::GetSpecMapData( ) { return &m_mapSpecXData; } void CBaseDialog::SetRoomFeature(const AecDbEarthWorm *pEw) { if (!pEw) return; m_roomTypes.clear(); CString str(_T("")), feature(_T("")); for (int i = 0; i < pEw->GetRoomCount(); ++i) { str.Format(_T("%d"), i); const AecDbObjXDataMap *pMap = pEw->GetSpecialtyData(); if (pMap) { pMap->GetAt(str, feature); //m_mapIndexToName.SetAt(str, feature); m_roomTypes.push_back(feature); } } } void CBaseDialog::SetRoomFeature(const AcDbObjectId &id) { OPENOBJ_BEGIN(id, AcDb::kForRead, AecDbEarthWorm, pEw) if (pEw) { const AecDbEarthWorm *p(pEw); m_roomTypes.clear(); CString str(_T("")), feature(_T("")); for (int i = 0; i < p->GetRoomCount(); ++i) { str.Format(_T("%d"), i); const AecDbObjXDataMap *pMap = p->GetSpecialtyData(); if (pMap) { pMap->GetAt(str, feature); //m_mapIndexToName.SetAt(str, feature); m_roomTypes.push_back(feature); } } } OPENOBJ_END() } bool CBaseDialog::CheckRoom(const double dCheck, int idxRoom) { CString str(_T("")); str.Format(_T("%d"), (int)(dCheck + .2f)); CString sPos(_T("")); sPos.Format(_T("%d"), idxRoom + 1); if (str.Find(sPos) == -1) return false; return true; } BOOL CBaseDialog::OnInitDialog() { CDialog::OnInitDialog(); // 存在 gsview 控件 if (m_idGSView != -1) { // 子类化控件对象 if (!m_wndViewCtrl.SubclassDlgItem(m_idGSView, this)) { // 错误时,结束对话框 EndDialog(IDCANCEL); return FALSE; } ShowEarthWorm(); if (IsInplaceEdit()) { SelectRoom(m_data.nRoomIndex); } } if (!IsInplaceEdit()) UIDataCache::FindNode(m_sTag, &m_data); return TRUE; } extern bool PickBoundary(const AcDbVoidPtrArray& arEntPtrs,const AcGePoint3d& ptHit,AcGePoint2d& ptSize,AcGePoint3d& ptLB); LRESULT CBaseDialog::OnViewLButtonDown(WPARAM wp, LPARAM lp) { if (m_idGSView == -1) return 0L; AcGePoint3d* pPt = (AcGePoint3d*)lp; pPt->z = 0.0; //判断 点落在 room 内 AecDbEarthWorm worm; worm.SetCrossSectionScr(m_sCrossSectionScr); worm.SetChamferInter(100.0); ESection eType = eRect; AcGePoint2dArray arDatas; eType = worm.ExtractEarthWormScr(arDatas); AcGeLineSeg3d ln; AcGePoint3d pt2(1000.0, 0, 0); ln.set(AcGePoint3d::kOrigin, pt2); AcDbRegion* pEWRegion = worm.CreateSectionRegion(ln, eType, arDatas); Acad::ErrorStatus es; AcDbRegion* pRegIn = NULL; AcDbEntity* pEnt = NULL; AcDbVoidPtrArray arr2; worm.CreateSectionRoomAddition(ln,eType,arr2); for (int i = 0; i < arr2.length(); i++) { pEnt = (AcDbEntity*)arr2.at(i); pRegIn = AcDbRegion::cast(pEnt); if (pRegIn != NULL) { es = pEWRegion->booleanOper(AcDb::kBoolUnite,pRegIn); } else { DELETE_PTR(pEnt); } } AcGePoint3d ptGe[4]; AcDbVoidPtrArray arRegPtrs; int nRooms = worm.CreateSectionRoomRegion(ln, eType, arDatas, arRegPtrs); if (nRooms > 0) { AcDbRegion* pReg = NULL; for (int i = 0; i < arRegPtrs.length(); i++) { pReg = (AcDbRegion*)arRegPtrs.at(i); if (pReg != NULL) { AcDbExtents ext; pReg->getGeomExtents(ext); ptGe[0] = ext.minPoint(); ptGe[1] = ptGe[0]; ptGe[1].x = ext.maxPoint().x; ptGe[2] = ext.maxPoint(); ptGe[3] = ptGe[0]; ptGe[3].y = ext.maxPoint().y; if (KTCADUtilityEx::IsPointInBoundary(*pPt, ptGe[0], ptGe[2])) { SetIdxOfRoom(i); AcGsView* pView = m_wndViewCtrl.view(); AcGsModel* pModel = m_wndViewCtrl.model(); //在进一步确定rectcell if (pEWRegion != NULL) { AcDbVoidPtrArray arCurvePtrs; pEWRegion->explode(arCurvePtrs); AcGePoint2d ptSize; AcGePoint3d ptLB; if ( PickBoundary(arCurvePtrs,*pPt,ptSize,ptLB) ) { ptGe[0] = ptLB; ptGe[1] = ptGe[0]; ptGe[1].x = ptLB.x + ptSize.x; ptGe[2] = ptLB; ptGe[2].x += ptSize.x; ptGe[2].y += ptSize.y; ptGe[3] = ptGe[0]; ptGe[3].y = ptLB.y + ptSize.y; } //FreeBuffer(arCurvePtrs); } if (pView != NULL) { if (m_pRectCell != NULL) pView->erase(m_pRectCell); } if (m_pRectCell != NULL) { for (int i = 0; i < 4; i++) { m_pRectCell->setPointAt(i, ptGe[i].convert2d(AcGePlane::kXYPlane)); } } if (pView != NULL) { pView->add(m_pRectCell, pModel); } break; } } } if (GetIdxOfRoom() == -1) { m_pRectCell->setPointAt(0, AcGePoint2d::kOrigin); m_pRectCell->setPointAt(1, AcGePoint2d(1, 0)); m_pRectCell->setPointAt(2, AcGePoint2d(1, 1)); m_pRectCell->setPointAt(3, AcGePoint2d(0, 1)); } FreeBuffer(arRegPtrs); m_wndViewCtrl.view()->invalidate(); m_wndViewCtrl.RedrawWindow(); OnViewLButtonDownMsg(); } return 0L; } void CBaseDialog::OnOK() { UIDataCache::WriteNode(m_sTag, &m_data); CDialog::OnOK(); } void CBaseDialog::OnViewLButtonDownMsg() { return; } extern bool PickBoundary(const AcDbVoidPtrArray& arEntPtrs,const AcGePoint3d& ptHit,AcGePoint2d& ptSize,AcGePoint3d& ptLB); void CBaseDialog::SelectRoom(int idx) { if (m_idGSView == -1) return; if (idx < 0) return; AcGsView* pView = m_wndViewCtrl.view(); AcGsModel* pModel = m_wndViewCtrl.model(); if (!pView) return; if (!pModel) return; if (!m_pRectCell) return; if (m_sCrossSectionScr.IsEmpty()) return; AecDbEarthWorm worm; worm.SetCrossSectionScr(m_sCrossSectionScr); worm.SetChamferInter(100.0); ESection eType = eRect; AcGePoint2dArray arDatas; eType = worm.ExtractEarthWormScr(arDatas); AcGeLineSeg3d ln; AcGePoint3d pt2(1000.0, 0, 0); ln.set(AcGePoint3d::kOrigin, pt2); AcDbVoidPtrArray arRegPtrs; int nRooms = worm.CreateSectionRoomRegion(ln, eType, arDatas, arRegPtrs); if (nRooms <= 0) return; if (nRooms <= idx) return; // 取出红框的几何数据 AcDbRegion* pReg = NULL; pReg = (AcDbRegion*)arRegPtrs.at(idx); if (!pReg) return; //传入的舱体号保存到对话框中 SetIdxOfRoom(idx); AcDbExtents ext; pReg->getGeomExtents(ext); AcGePoint3d ptGe[4]; ptGe[0] = ext.minPoint(); ptGe[1] = ptGe[0]; ptGe[1].x = ext.maxPoint().x; ptGe[2] = ext.maxPoint(); ptGe[3] = ptGe[0]; ptGe[3].y = ext.maxPoint().y; pView->erase(m_pRectCell); for (int i = 0; i < 4; i++) { m_pRectCell->setPointAt(i, ptGe[i].convert2d(AcGePlane::kXYPlane)); } pView->add(m_pRectCell, pModel); FreeBuffer(arRegPtrs); pView->invalidate(); m_wndViewCtrl.RedrawWindow(); } int CBaseDialog::GetDrawBuffer(AcDbVoidPtrArray& arDrawbuffer) const { if (!m_arDrawBuffer.isEmpty()) { AcDbEntity* pEnt = NULL,*pEntClone = NULL; for (int i = 0;i < m_arDrawBuffer.length();i++) { pEnt = (AcDbEntity*)m_arDrawBuffer.at(i); if (pEnt != NULL) { AcDbRegion* pReg = AcDbRegion::cast(pEnt); if (pReg != NULL) { pReg->explode(arDrawbuffer); } else { pEntClone = (AcDbEntity*)pEnt->clone(); arDrawbuffer.append(pEntClone); } } } } return m_arDrawBuffer.length(); }