#include "stdafx.h" #include "DLJCDlg.h" #include "coretools.h" #include "KTCadUtility.h" #include "KTSetting.h" #include "AecDbSlab.h" #include "AecDbMultiPartEntity.h" IMPLEMENT_DYNAMIC(CDLJCDlg, CDialog) CDLJCDlg::CDLJCDlg(CWnd* pParent ) : CDialog(IDD_DLJC_DLG, pParent) , m_dBaseThick(100) , m_dBaseOffset(100) , m_dSuTongThick(200) , m_dSuTongOffset(200) , m_bHasSuTong(FALSE) , m_iClrBase(256) , m_iClrSuTong(256) { GET_CACHE(CDLJCDlg , %f%f%f%f%d%d%d , &m_dBaseThick , &m_dBaseOffset , &m_dSuTongThick , &m_dSuTongOffset , &m_bHasSuTong , &m_iClrBase , &m_iClrSuTong ); } CDLJCDlg::~CDLJCDlg() { } void CDLJCDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT_BASE_THICK, m_dBaseThick); DDX_Text(pDX, IDC_EDIT_BASE_OFFSET, m_dBaseOffset); DDX_Text(pDX, IDC_EDIT_SUTONG_THICK, m_dSuTongThick); DDX_Text(pDX, IDC_EDIT_SUTONG_OFFSET, m_dSuTongOffset); DDX_Check(pDX, IDC_CHECK_SUTONG, m_bHasSuTong); } BOOL CDLJCDlg::OnInitDialog() { CDialog::OnInitDialog(); UpdateData(FALSE); return TRUE; } BEGIN_MESSAGE_MAP(CDLJCDlg, CDialog) ON_BN_CLICKED(IDOK, &CDLJCDlg::OnBnClickedOk) ON_BN_CLICKED(IDC_CHECK_SUTONG, &CDLJCDlg::OnBnClickedCheckSutong) ON_BN_CLICKED(IDC_STATIC_COLOR_BASE, &CDLJCDlg::OnStaticColorBase) ON_BN_CLICKED(IDC_STATIC_COLOR_SUTONG, &CDLJCDlg::OnStaticColorSuTong) ON_WM_CTLCOLOR() END_MESSAGE_MAP() void CDLJCDlg::OnBnClickedOk() { if (!UpdateData()) return; SET_CACHE(CDLJCDlg , %f%f%f%f%d%d%d , m_dBaseThick , m_dBaseOffset , m_dSuTongThick , m_dSuTongOffset , m_bHasSuTong , m_iClrBase , m_iClrSuTong ); CDialog::OnOK(); } void CDLJCDlg::OnStaticColorBase() { AcCmColor clr; #if ARX < 24 clr.setColorMethod(AcCmEntityColor::kByACI); #endif clr.setColorIndex(m_iClrBase); if (acedSetColorDialogTrueColor(clr, Adesk::kTrue, clr, (AcCm::DialogTabs)(AcCm::kACITab)) == Adesk::kFalse) return; m_iClrBase = clr.colorIndex(); Invalidate(); } void CDLJCDlg::OnStaticColorSuTong() { AcCmColor clr; #if ARX < 24 clr.setColorMethod(AcCmEntityColor::kByACI); #endif clr.setColorIndex(m_iClrSuTong); if (acedSetColorDialogTrueColor(clr, Adesk::kTrue, clr, (AcCm::DialogTabs)(AcCm::kACITab)) == Adesk::kFalse) return; m_iClrSuTong = clr.colorIndex(); Invalidate(); } void CDLJCDlg::OnBnClickedCheckSutong() { if (!UpdateData()) return; CWnd *pWnd = GetDlgItem(IDC_EDIT_SUTONG_THICK); if (pWnd) pWnd->EnableWindow(m_bHasSuTong); pWnd = GetDlgItem(IDC_EDIT_SUTONG_OFFSET); if (pWnd) pWnd->EnableWindow(m_bHasSuTong); } HBRUSH CDLJCDlg::OnCtlColor(CDC *pDC, CWnd *pWnd, UINT nCtlColor) { HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); if (nCtlColor == CTLCOLOR_STATIC && pWnd != NULL) { if (pWnd->GetDlgCtrlID() == IDC_STATIC_COLOR_BASE) { CRect rc; pWnd->GetClientRect(rc); pDC->FillSolidRect(rc, acedGetRGB(m_iClrBase)); } else if (pWnd->GetDlgCtrlID() == IDC_STATIC_COLOR_SUTONG) { CRect rc; pWnd->GetClientRect(rc); pDC->FillSolidRect(rc, acedGetRGB(m_iClrSuTong)); } } return hbr; } namespace { 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); } } AecDbMultiPartEntity *makeEntity(const AcGePoint3d &pt , AcDbCurve *pCurve , const double &dThick , LPCTSTR name , LPCTSTR app , LPCTSTR ma , int clr) { if (abs(dThick) < .1) { acutPrintf(_T("\n上下距离过小,放弃生成.")); return NULL; } if (!pCurve) return NULL; std::shared_ptr spReg(CoreTools::createRegion(pCurve)); if (!spReg) return NULL; std::shared_ptr spDwnReg((AcDbRegion*)spReg->clone()); if (!spDwnReg) return NULL; AcDbCircle cir(pt, AcGeVector3d::kZAxis, .001); AcDbLine baseLine(pt, pt + AcGeVector3d::kZAxis * .001); std::shared_ptr spBaseReg(CoreTools::createRegion(&cir)); if (!spBaseReg) return NULL; AcGeMatrix3d mat; mat.setToTranslation(AcGeVector3d::kZAxis * -dThick); spDwnReg->transformBy(mat); AcArray ar; ar.append(spReg.get()); ar.append(spDwnReg.get()); AecDbMultiPartEntity *pEnt = new AecDbMultiPartEntity(); pEnt->SetBaseCurve(&baseLine); pEnt->SetSection(spBaseReg.get(), pt); pEnt->SetOrg(pt); 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); AcDbLine Line(pt, pt - AcGeVector3d::kZAxis * dThick); AcDbX3dSolid *pSolid = new AcDbX3dSolid(); if (pSolid->CreateLoft(ar, NULL)) { AecDbX3dPart *pPart = new AecDbX3dPart(); pPart->GetSpecialtyData()->SetAt(_T("DTYG_TYPE"), _T("放样体")); pPart->GetSpecialtyData()->SetAt(_T("MAIN"), TRUE); pPart->AddX3dSolid(pSolid); pPart->SetOrgPoint(pSolid->GetCentoridPoint()); pPart->SetAxis(0, AcGeVector3d::kXAxis); pPart->SetAxis(1, AcGeVector3d::kYAxis); pPart->SetAxis(2, AcGeVector3d::kZAxis); setBIMData(pPart->GetSpecialtyData(), name, clr, ma, app); pPart->SetName(name); pEnt->AddX3dPart(pPart, AcDb::kBoolUnite); pEnt->SetAt(_T("DLJC"), TRUE); pEnt->SetAt(_T("NAME"), name); setBIMData(pEnt->GetSpecialtyData(), name, clr, ma, app); } else { DELETE_PTR(pSolid); DELETE_PTR(pEnt); return NULL; } return pEnt; } } extern AcDbCurve *GetOffsetCurve(AcDbCurve*, double , bool ); void CDLJCDlg::start() { #if ARX >= 19 CAcModuleResourceOverride myResources; AcDbObjectId id; { ads_name ent; struct resbuf *pRb = acutBuildList(RTDXF0, _T("AEC_DBSLAB"), 0); int nRes = CKTCadUtility::SelectEntity(_T("\n选择一块底板<退出>:"), ent, pRb); acutRelRb(pRb); if (nRes != RTNORM) return; acdbGetObjectId(id, ent); if (!id.isValid()) return; } CDLJCDlg dlg; if (dlg.DoModal() != IDOK) return; AcDbObjectPointer slab(id, AcDb::kForRead); if (slab.openStatus() != Acad::eOk) return; AcDbCurve *pCurve = slab->GetBasinShapeCurve(); AcGePoint3d ptCurveCen; // 得到pCurve的中心点 { AcDbExtents ext; pCurve->getGeomExtents(ext); ptCurveCen = CoreTools::MidPt(ext.maxPoint(), ext.minPoint()); } AcGePoint3d ptCen; // 板的对齐点(最低点) AcGeMatrix3d xRote, yRote; { // 构建出平板的旋转矩阵 slab->GetAt(KEY_ORGPT, ptCen); CString sGradX, sGradY; slab->GetAt(KEY_GRADX, sGradX); slab->GetAt(KEY_GRADY, sGradY); double dA = atan(_ttof(sGradX) / 100.0); double dB = atan(_ttof(sGradY) / 100.0); xRote.setToRotation(dA, AcGeVector3d::kYAxis, ptCen); yRote.setToRotation(dB, AcGeVector3d::kXAxis, ptCen); } { // 首先,得到的截面不会倾斜,都是水平的。 // 底板截面有两种情况,一种是在板上,另一种是在板下。由生成板的闭合曲线的法线决定. // 通过判断 KEY_ORGPT 点,可以得到板的底标高。直接将截面移动过去 AcGeMatrix3d mat; mat.setToTranslation(AcGeVector3d::kZAxis * (ptCen.z - ptCurveCen.z)); pCurve->transformBy(mat); } double dAngle(.0); { // 计算板旋转后和平面的夹角 AcDb::Planarity planarity; AcGePlane pln; if (pCurve->getPlane(pln, planarity) != Acad::eOk) return; AcGeVector3d vt(pln.normal()); vt.transformBy(xRote); vt.transformBy(yRote); dAngle = vt.angleTo(AcGeVector3d::kZAxis); } // 此时的 pCurve 已经在板的下表面,但没有旋转 // 根据交互,判断是生成一个层还是两个 {// 先生成基础 AcDbCurve *pNewCurve = GetOffsetCurve(pCurve, dlg.m_dBaseOffset, dlg.m_dBaseOffset > 0 ? false : true); if (!pNewCurve) return; pNewCurve->transformBy(xRote); pNewCurve->transformBy(yRote); AecDbMultiPartEntity *pEnt = makeEntity(ptCen , pNewCurve , dlg.m_dBaseThick / cos(dAngle) , _T("板基础") , _T("其他") , _T("钢筋混凝土") , dlg.m_iClrBase ); DELETE_PTR(pNewCurve); if (pEnt) { CoreTools::AddToModelSpace(pEnt); } } // 再生成素砼 if (dlg.m_bHasSuTong) { // pCurve再向下移动板基础的厚度 AcGeMatrix3d mat; mat.setToTranslation(-AcGeVector3d::kZAxis * dlg.m_dBaseThick); pCurve->transformBy(mat); AcDbCurve *pNewCurve = GetOffsetCurve(pCurve, dlg.m_dSuTongOffset, dlg.m_dSuTongOffset > 0 ? false : true); if (!pNewCurve) return; pNewCurve->transformBy(xRote); pNewCurve->transformBy(yRote); AecDbMultiPartEntity *pEnt = makeEntity(ptCen , pNewCurve , dlg.m_dSuTongThick / cos(dAngle) , _T("素砼") , _T("其他") , _T("钢筋混凝土") , dlg.m_iClrSuTong); DELETE_PTR(pNewCurve); if (pEnt) { CoreTools::AddToModelSpace(pEnt); } } DELETE_PTR(pCurve); #else AfxMessageBox(_T("请使用AutoCAD2013及以上版本。")); #endif }