#include "stdafx.h" #include "compare_double.h" #include "KTCadUtility.h" #include "KTSetting.h" #include "coretools.h" #include "PMFYDlg.h" #include "GLTKDlg.h" #include "AecDbMultiPartEntity.h" namespace { AcDbRegion* string2Region(LPCTSTR str) { if (!str) return NULL; CString sFullPath = FilePath::getSystemTemporaryFolder(); sFullPath.MakeLower(); sFullPath += _T("\\pmfy.sat"); CStdioFile file; if (!file.Open(sFullPath, CFile::modeCreate |CFile::modeWrite)) return NULL; file.WriteString(str); file.Close(); AcDbVoidPtrArray arBodyPtrs; if (Acad::eOk != AcDbBody::acisIn(sFullPath, arBodyPtrs)) return NULL; if (arBodyPtrs.isEmpty()) return NULL; return AcDbRegion::cast((AcDbEntity*)arBodyPtrs.first()); } AcDbRegion* selectRegion(CString &src) { src.Empty(); CAcModuleResourceOverride myResources; CGLTKDlg dlg(CGLTKDlg::eSelect, _T("poolstandard.db"), _T("standard"), CGLTKDlg::drawRegion); if (IDOK != dlg.DoModal()) return NULL; CString sScr; if (!dlg.GetCrossSectionScr(sScr)) return NULL; AcDbRegion *pReg(string2Region(sScr)); if (pReg) src = sScr; return pReg; } void transformRegion(AcDbRegion *pReg , const AcDbCurve *pCurve , const bool &bStartPoint) { if (!pReg || !pCurve) return; AcGePoint3d pt; AcGeVector3d vt; if (bStartPoint) pCurve->getStartPoint(pt); else pCurve->getEndPoint(pt); pCurve->getFirstDeriv(pt, vt); AcGeVector3d vtAxis(AcGeVector3d::kZAxis.crossProduct(vt)); AcGeMatrix3d mat; AcGePlane pln(pt, vt); mat.setToWorldToPlane(pln); pReg->transformBy(mat.inverse()); } // pLine,0标高,把pReg1, pReg2移动到两端 void transformRegion2(AcDbLine *pLine , AcDbRegion *pReg1 , AcDbRegion *pReg2 ) { if (!pReg1 || !pReg2 || !pLine) return; AcGePoint3d ptS(pLine->startPoint()), ptE(pLine->endPoint()); AcGeVector3d vt((ptE - ptS).normalize()); vt.z = .0; AcGeMatrix3d mat; AcGePlane plnS(ptS, vt), plnE(ptE, vt); mat.setToWorldToPlane(plnS); pReg1->transformBy(mat.inverse()); mat.setToWorldToPlane(plnE); pReg2->transformBy(mat.inverse()); } CString getClrString(int idx, bool hasHead = true) { CString sClr(_T("")), s(_T("")); if (idx == 0) sClr = _T("ByBlock"); else if (idx == 256) sClr = _T("ByLayer"); else sClr.Format(_T("%d"), idx); s.Format(_T("%s:%s"), _T("颜色"), sClr); if (hasHead) return s; return sClr; } void setBIMData(AecDbObjXDataMap *pMap , LPCTSTR pszName , int clr , LPCTSTR pszMaterials , LPCTSTR pszApp ) { CString s(_T("")); SH_BIM_BLOCK bims; CoreTools::getBimDatas(*pMap, bims); if (bims.empty()) { if (pszName) bims.push_back(std::make_pair(_T("名称"), pszName)); bims.push_back(std::make_pair(_T("颜色"), getClrString(clr, false))); if (pszMaterials) bims.push_back(std::make_pair(_T("材料"), pszMaterials)); if (pszApp) bims.push_back(std::make_pair(_T("统计类型"), pszApp)); CoreTools::setBimDatas(*pMap, bims); } else { if (pszName) CoreTools::setBimData(*pMap, _T("名称"), pszName); CoreTools::setBimData(*pMap, _T("颜色"), getClrString(clr, false)); if (pszMaterials) CoreTools::setBimData(*pMap, _T("材料"), pszMaterials); if (pszApp) CoreTools::setBimData(*pMap, _T("统计类型"), pszApp); } } //修改pCurve的起点和终点标高 void modifyPathCurve(AcDbCurve *&pCurve, const double &dStart, const double &dEnd) { #if ARX >= 19 if (!pCurve) return; if (COMPARE_DOUBLE::equal_zero(dStart) && COMPARE_DOUBLE::equal_zero(dEnd)) return; AcGePoint3d ptStart, ptEnd, ptMid; pCurve->getStartPoint(ptStart); pCurve->getEndPoint(ptEnd); double dL(.0); pCurve->getDistAtPoint(ptEnd, dL); pCurve->getPointAtDist(dL * .5, ptMid); ptStart.z = dStart; ptEnd.z = dEnd; AcGeVector3d vtN(ptEnd - ptStart); vtN.normalize(); AcGeVector3d vtAxis(vtN.crossProduct(AcGeVector3d::kZAxis)); vtAxis.normalize(); vtN.rotateBy(PI * .5, vtAxis); AcGePlane plnNew(ptStart, vtN); std::shared_ptr spGeCrv; AcGeCurve3d *pGeCrv(NULL); if (pCurve->getAcGeCurve(pGeCrv) != Acad::eOk) return; if (!pGeCrv) return; spGeCrv.reset(pGeCrv); std::shared_ptr spGeOrtho; AcGeEntity3d *pGeOrtho = pGeCrv->orthoProject(plnNew); if (!pGeOrtho) return; spGeOrtho.reset(pGeOrtho); AcGe::EntityId type = spGeOrtho->type(); if (type == AcGe::kCircArc3d) { AcDbArc *pDbArc = CoreTools::geArc2DbArc(*(AcGeCircArc3d*)spGeOrtho.get()); DELETE_PTR(pCurve); pCurve = pDbArc; } else if (type == AcGe::kLineSeg3d) { AcGeLineSeg3d *seg = (AcGeLineSeg3d*)spGeOrtho.get(); AcDbLine *pLine = new AcDbLine(seg->startPoint(), seg->endPoint()); DELETE_PTR(pCurve); pCurve = pLine; } else if (type == AcGe::kEllipArc3d) { AcGeEllipArc3d *pGeArc = (AcGeEllipArc3d *)spGeOrtho.get(); AcDbEllipse *pDbEll = new AcDbEllipse(pGeArc->center() , pGeArc->normal() , pGeArc->majorAxis().normalize() * pGeArc->majorRadius() , pGeArc->minorRadius() / pGeArc->majorRadius() , pGeArc->startAng() , pGeArc->endAng()); DELETE_PTR(pCurve); pCurve = pDbEll; } else if (type == AcGe::kNurbCurve3d) { AcGeNurbCurve3d *pGeNurb = (AcGeNurbCurve3d*)spGeOrtho.get(); bool bFitCurve = pGeNurb->hasFitData(); AcDbSpline *pDbSp = new AcDbSpline(); if (bFitCurve) { AcGePoint3dArray fitPoints; AcGeTol fitTolerance; Adesk::Boolean tangentsExist; AcGeVector3d startTangent, endTangent; KnotParameterization knotParam; pGeNurb->getFitData(fitPoints , fitTolerance , tangentsExist , startTangent , endTangent , knotParam); pDbSp->setType(kFitPoints); pDbSp->setFitData(fitPoints , startTangent , endTangent , knotParam , pGeNurb->degree() , fitTolerance.equalPoint()); } else { int degree; Adesk::Boolean rational, periodic; AcGeKnotVector knots; AcGePoint3dArray controlPoints; AcGeDoubleArray weights; pGeNurb->getDefinitionData(degree , rational , periodic , knots , controlPoints , weights); pDbSp->setType(kControlPoints); AcGeDoubleArray arKnots(knots.length()); ::memcpy(arKnots.asArrayPtr(), knots.asArrayPtr(), sizeof(double) * knots.length()); arKnots.setLogicalLength(knots.logicalLength()); pDbSp->setNurbsData(degree , rational , pGeNurb->isClosed() , periodic , controlPoints , arKnots , weights , .0 , knots.tolerance()); } DELETE_PTR(pCurve); pCurve = pDbSp; } #else return; #endif } } IMPLEMENT_DYNAMIC(CPMFYDlg, CDialog) CPMFYDlg::CPMFYDlg(CWnd *pParent) : CDialog(IDD_PMFY_DLG, pParent) , m_dElevStart(0) , m_dElevEnd(0) , m_clr(256) , m_sName(_T("放样体")) , m_pPathCurve(NULL) , m_pStartRegion(NULL) , m_pEndRegion(NULL) , m_strStartRegion(_T("")) , m_strEndRegion(_T("")) , m_strPath(_T("")) , m_bInplace(false) , m_sMaterial(_T("钢筋混凝土")) , m_sApplication(_T("其他")) , m_idInplace(AcDbObjectId::kNull) { GET_CACHE(CPMFYDlg , %f%f%s%s%s , &m_dElevStart , &m_dElevEnd , &m_sName , &m_sMaterial , &m_sApplication ); } bool CPMFYDlg::fromID(AcDbObjectId &id) { if (!::IsWindow(g_PmfyDlg::instance().m_hWnd)) return false; AcDbObjectPointer pInplaceEnt(id, AcDb::kForRead); if (pInplaceEnt.openStatus() != Acad::eOk) return false; clear(); do { BOOL isPMFY(FALSE); pInplaceEnt->GetAt(_T("PMFY"), isPMFY); if (!isPMFY) break; AecDbX3dPart *pPart(NULL); AcDbX3dSolid *pSolid(NULL); if (!findMainPart(pInplaceEnt, pPart, pSolid)) break; if (!pPart) break; if (!pSolid) break; if (!pPart->GetSpecialtyData()->GetAt(_T("START_REGION"), m_strStartRegion)) break; if (!pPart->GetSpecialtyData()->GetAt(_T("END_REGION"), m_strEndRegion)) break; if (!pPart->GetSpecialtyData()->GetAt(_T("PATH"), m_strPath)) break; if (!pPart->GetSpecialtyData()->GetAt(_T("START_ELEV"), m_dElevStart)) break; if (!pPart->GetSpecialtyData()->GetAt(_T("END_ELEV"), m_dElevEnd)) break; m_pPathCurve = CoreTools::StringToAcDbCurve(m_strPath); m_pStartRegion = string2Region(m_strStartRegion); m_pEndRegion = string2Region(m_strEndRegion); if (!m_pPathCurve || !m_pStartRegion || !m_pEndRegion) { clear(); break; } // 所有检查都没有问题 m_idInplace = id; m_bInplace = true; pPart->GetName(m_sName); CString clr; CoreTools::getBimData(*pPart->GetSpecialtyData(), _T("颜色"), clr); m_clr = TypeConvert::s2i(clr); CoreTools::getBimData(*pPart->GetSpecialtyData(), _T("材料"), m_sMaterial); CoreTools::getBimData(*pPart->GetSpecialtyData(), _T("统计类型"), m_sMaterial); UpdateData(FALSE); return true; } while (false); return false; } CPMFYDlg::~CPMFYDlg() { clear(); } BOOL CPMFYDlg::OnInitDialog() { CDialog::OnInitDialog(); UpdateData(FALSE); return TRUE; } void CPMFYDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT_ELEV_START, m_dElevStart); DDX_Text(pDX, IDC_EDIT_ELEV_END, m_dElevEnd); DDX_Text(pDX, IDC_EDIT_NAME, m_sName); DDX_CBString(pDX, IDC_CMB_MA, m_sMaterial); DDX_CBString(pDX, IDC_CMB_APP, m_sApplication); } bool CPMFYDlg::findMainPart(AecDbMultiPartEntity *pM , AecDbX3dPart *&pPart , AcDbX3dSolid *&pSolid) { BOOL bMain(FALSE); int nCount(pM->GetX3dPartCount()); if (nCount <= 0) return false; for (int i(0); i < nCount; ++i) { AecDbX3dPart *pP(pM->GetX3dPart(i)); if (!pP) continue; bMain = FALSE; pP->GetSpecialtyData()->GetAt(_T("MAIN"), bMain); if (bMain) { if (pP->GetX3dSolidCount(AcDb::kBoolUnite) > 0) { AcDbX3dSolid *pS = pP->GetX3dSolid(0); if (pS->GetSolidType() == AcDbX3dSolid::kLoft) { pPart = pP; pSolid = pS; return true; } } } } return false; } bool CPMFYDlg::NewEntity(const AcArray &arRegs) { AecDbMultiPartEntity *pEnt = new AecDbMultiPartEntity(); { AcGePoint3d ptS; if (m_pPathCurve->getStartPoint(ptS) != Acad::eOk) { DELETE_PTR(pEnt); return false; } pEnt->SetAt(_T("PMFY"), TRUE); pEnt->SetAt(_T("NAME"), m_sName); double l(.01), h(.01); AcDbCircle cir(ptS, AcGeVector3d::kZAxis, l); AcDbLine line(ptS, ptS + AcGeVector3d::kZAxis * h); AcDbRegion *pReg = CoreTools::createRegion(&cir); if (!pReg) { DELETE_PTR(pEnt); return false; } pEnt->SetBaseCurve(&line); pEnt->SetSection(pReg, ptS); DELETE_PTR(pReg); pEnt->SetOrg(ptS); pEnt->SetXDir(AcGeVector3d::kXAxis); pEnt->SetYDir(AcGeVector3d::kYAxis); pEnt->SetZDir(AcGeVector3d::kZAxis); AcDbObjectId idYGDTLay = KTSetting::InitLayer(_T("LAY_YGDT"), true); if (idYGDTLay.isValid()) pEnt->setLayer(idYGDTLay); } AcDbX3dSolid *pSolid = new AcDbX3dSolid(); //if (pSolid->CreateLoft(arRegs, m_pPathCurve)) if (pSolid->CreateLoft(arRegs)) { AecDbX3dPart *pPart = new AecDbX3dPart(); pPart->GetSpecialtyData()->SetAt(_T("DTYG_TYPE"), _T("放样体")); pPart->GetSpecialtyData()->SetAt(_T("MAIN"), TRUE); pPart->AddX3dSolid(pSolid); pPart->SetOrgPoint(pSolid->GetCentoridPoint()); setXPartInfo(pPart); pEnt->AddX3dPart(pPart, AcDb::kBoolUnite); CoreTools::AddToModelSpace(pEnt); return true; } else { AfxMessageBox(_T("生成失败。")); DELETE_PTR(pSolid); DELETE_PTR(pEnt); } return false; } bool CPMFYDlg::InplaceEntity(const AcArray &arRegs) { AcDbObjectPointer ent(m_idInplace, AcDb::kForWrite); if (ent.openStatus() != Acad::eOk) return false; ent->AssertWriteEnabled(); AecDbX3dPart *pPart(NULL); AcDbX3dSolid *pSolid(NULL); if (!findMainPart(ent, pPart, pSolid)) return false; if (pSolid->CreateLoft(arRegs, m_pPathCurve)) { pPart->SetOrgPoint(pSolid->GetCentoridPoint()); setXPartInfo(pPart); pPart->Create(); } return true; } void CPMFYDlg::setXPartInfo(AecDbX3dPart *pPart) { if (!pPart) return; pPart->SetAxis(0, AcGeVector3d::kXAxis); pPart->SetAxis(1, AcGeVector3d::kYAxis); pPart->SetAxis(2, AcGeVector3d::kZAxis); setBIMData(pPart->GetSpecialtyData(), m_sName, m_clr, m_sMaterial, m_sApplication); pPart->SetName(m_sName); pPart->GetSpecialtyData()->SetAt(_T("START_REGION"), m_strStartRegion); pPart->GetSpecialtyData()->SetAt(_T("END_REGION"), m_strEndRegion); pPart->GetSpecialtyData()->SetAt(_T("PATH"), m_strPath); pPart->GetSpecialtyData()->SetAt(_T("START_ELEV"), m_dElevStart); pPart->GetSpecialtyData()->SetAt(_T("END_ELEV"), m_dElevEnd); } BEGIN_MESSAGE_MAP(CPMFYDlg, CDialog) ON_BN_CLICKED(IDOK, &CPMFYDlg::OnBnClickedOk) ON_BN_CLICKED(IDC_BTN_PATH, &CPMFYDlg::OnBnClickedBtnPath) ON_BN_CLICKED(IDC_BTN_SECTION_START, &CPMFYDlg::OnBnClickedBtnSectionStart) ON_BN_CLICKED(IDC_BTN_SECTION_END, &CPMFYDlg::OnBnClickedBtnSectionEnd) ON_BN_CLICKED(IDC_STATIC_COLOR, &CPMFYDlg::OnStaticColor) ON_MESSAGE(WM_ACAD_KEEPFOCUS, &CPMFYDlg::onAcadKeepFocus) ON_WM_CLOSE() ON_WM_SHOWWINDOW() ON_WM_CTLCOLOR() END_MESSAGE_MAP() void CPMFYDlg::OnBnClickedOk() { AcAxDocLock lock; if (!UpdateData(TRUE)) return; if (!m_pPathCurve) { AfxMessageBox(_T("请选择路径!")); return; } if (!m_pStartRegion && !m_pEndRegion) { AfxMessageBox(_T("请选择一个截面!")); } if (!m_pStartRegion && m_pEndRegion) { m_pStartRegion = (AcDbRegion*)m_pEndRegion->clone(); m_strStartRegion = m_strEndRegion; } if (!m_pEndRegion && m_pStartRegion) { m_pEndRegion = (AcDbRegion*)m_pStartRegion->clone(); m_strEndRegion = m_strStartRegion; } // 只处理直线 //modifyPathCurve(m_pPathCurve, m_dElevStart, m_dElevEnd); AcDbLine *pLine(AcDbLine::cast(m_pPathCurve)); if (!pLine) return; AcGePoint3d pt(pLine->startPoint()); pt.z = m_dElevStart; pLine->setStartPoint(pt); pt = pLine->endPoint(); pt.z = m_dElevEnd; pLine->setEndPoint(pt); //transformRegion(m_pStartRegion, m_pPathCurve, true); //transformRegion(m_pEndRegion, m_pPathCurve, false); // 只处理直线 transformRegion2(pLine, m_pStartRegion, m_pEndRegion); AcArray arRegs; arRegs.append(m_pStartRegion); arRegs.append(m_pEndRegion); if (!m_bInplace) NewEntity(arRegs); else InplaceEntity(arRegs); clear(); SET_CACHE(CPMFYDlg , %f%f%s%s%s , m_dElevStart , m_dElevEnd , m_sName , m_sMaterial , m_sApplication); CDialog::OnOK(); } void CPMFYDlg::OnStaticColor() { AcCmColor clr; #if ARX < 24 clr.setColorMethod(AcCmEntityColor::kByACI); #endif clr.setColorIndex(256); if (acedSetColorDialogTrueColor(clr, Adesk::kTrue, clr, (AcCm::DialogTabs)(AcCm::kACITab)) == Adesk::kFalse) return; m_clr = clr.colorIndex(); Invalidate(); } HBRUSH CPMFYDlg::OnCtlColor(CDC *pDC, CWnd *pWnd, UINT nCtlColor) { HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); if (nCtlColor == CTLCOLOR_STATIC) { if (pWnd != NULL && pWnd->GetDlgCtrlID() == IDC_STATIC_COLOR) { CRect rc; pWnd->GetClientRect(rc); pDC->FillSolidRect(rc, acedGetRGB(m_clr)); } } return hbr; } bool CPMFYDlg::selectPath() { ads_name name; // 改为只支持直线 //struct resbuf *pRb = acutBuildList(RTDXF0, _T("LINE,ARC,SPLINE"), 0); struct resbuf *pRb = acutBuildList(RTDXF0, _T("LINE"), 0); int nRes = CKTCadUtility::SelectEntity(_T("\n请选择放样路径(直线):"), name, pRb); acutRelRb(pRb); if (nRes != RTNORM) return false; AcDbObjectId id; if (acdbGetObjectId(id, name) != Acad::eOk) return false; AcDbEntityPointer ent(id, AcDb::kForRead); if (ent.openStatus() != Acad::eOk) return false; DELETE_PTR(m_pPathCurve); m_pPathCurve = (AcDbCurve *)ent->clone(); m_strPath.Empty(); CoreTools::AcDbCurveToString(m_pPathCurve, m_strPath); return true; } void CPMFYDlg::OnBnClickedBtnPath() { ShowWindow(SW_HIDE); selectPath(); ShowWindow(SW_SHOW); } void CPMFYDlg::OnBnClickedBtnSectionStart() { ShowWindow(SW_HIDE); AcDbRegion *pReg(NULL); pReg = selectRegion(m_strStartRegion); if (pReg) { DELETE_PTR(m_pStartRegion); m_pStartRegion = pReg; } ShowWindow(SW_SHOW); } void CPMFYDlg::OnBnClickedBtnSectionEnd() { ShowWindow(SW_HIDE); AcDbRegion *pReg(NULL); pReg = selectRegion(m_strEndRegion); if (pReg) { DELETE_PTR(m_pEndRegion); m_pEndRegion = pReg; } ShowWindow(SW_SHOW); } LONG_PTR CPMFYDlg::onAcadKeepFocus(UINT_PTR, LONG_PTR) { POINT pt; ::GetCursorPos(&pt); CRect rect; GetWindowRect(&rect); if (!(rect.PtInRect(pt))) { return FALSE; } //如果当前有命令在执行中,提示 struct resbuf rb; acedGetVar(_T("CMDNAMES"), &rb); if (rb.restype == RTSTR && rb.resval.rstring != NULL) { if (_tcslen(rb.resval.rstring) > 0) { acedPostCommand(_T("\x03")); } } return TRUE; } void CPMFYDlg::clear() { m_bInplace = false; DELETE_PTR(m_pPathCurve); DELETE_PTR(m_pStartRegion); DELETE_PTR(m_pEndRegion); m_strPath.Empty(); m_strStartRegion.Empty(); m_strEndRegion.Empty(); } void CPMFYDlg::OnClose() { clear(); CDialog::OnClose(); } void CPMFYDlg::OnShowWindow(BOOL bShow, UINT nStatus) { if (bShow) { CWnd *pWnd(GetDlgItem(IDC_BTN_PATH)); if (pWnd) { if (m_pPathCurve) pWnd->SetWindowText(_T("选择放样路径✓")); else pWnd->SetWindowText(_T("选择放样路径")); } pWnd = GetDlgItem(IDC_BTN_SECTION_START); if (pWnd) { if (m_pStartRegion) pWnd->SetWindowText(_T("选择起点截面✓")); else pWnd->SetWindowText(_T("选择起点始截面")); } pWnd = GetDlgItem(IDC_BTN_SECTION_END); if (pWnd) { if (m_pEndRegion) pWnd->SetWindowText(_T("选择终点始截面✓")); else pWnd->SetWindowText(_T("选择终点始截面")); } } CDialog::OnShowWindow(bShow, nStatus); } ///////////////////////////////////////////////////////// void CPMFYDlg::start() { #if ARX >= 19 CAcModuleResourceOverride myResources; g_PmfyDlg::instance().selectPath(); if (!::IsWindow(g_PmfyDlg::instance().m_hWnd)) { g_PmfyDlg::instance().Create(CPMFYDlg::IDD, acedGetAcadFrame()); g_PmfyDlg::instance().CenterWindow(); } if (!g_PmfyDlg::instance().IsWindowVisible()) g_PmfyDlg::instance().ShowWindow(SW_SHOW); #else AfxMessageBox(_T("请使用AutoCAD2013及以上版本。")); #endif } void CPMFYDlg::inplace(AcDbObjectId &id) { #if ARX >= 19 CAcModuleResourceOverride myResources; if (!::IsWindow(g_PmfyDlg::instance().m_hWnd)) { g_PmfyDlg::instance().Create(CPMFYDlg::IDD, acedGetAcadFrame()); g_PmfyDlg::instance().CenterWindow(); } if (!g_PmfyDlg::instance().fromID(id)) return; if (!g_PmfyDlg::instance().IsWindowVisible()) g_PmfyDlg::instance().ShowWindow(SW_SHOW); #else AfxMessageBox(_T("请使用AutoCAD2013及以上版本。")); #endif }