#include "stdafx.h" #include "pmscdlg.h" #include "AecDbPoolCell.h" #include "CoreTools.h" #include "GLTKDlg.h" #include "PMSJDlg.h" #include "AecDbPoolCell.h" #include "AecDbWall.h" #include "AecDbSlab.h" #include #include "_cgal.h" #include "KTCadUtility.h" #include "KTCadUtilityEx.h" namespace { void generateBuilding( AcDbVoidPtrArray &arEnts , bool bColumn , bool bBeam , const AcGeMatrix3d &mat , const AcDbPolyline &_poly , const double &dInnerT // 内墙厚 , const double &dWallH // 墙高 , const double &dElevWall // 墙底标高 , const double &dSlabT // 板厚 , const double &dSlabElev // 板底标高 , const double &dColumnH // 柱高 , const double &dColumnL // 柱长 , const double &dColumnW // 柱宽 , const double &dElevColumn // 柱底标高 , const double &dBeamW // 梁宽 , const double &dBeamT // 梁厚 , const double &dBeamElev // 梁底标高 ) { if (_poly.numVerts() < 1) return; AcDbPolyline *poly = (AcDbPolyline*)_poly.clone(); if (_poly.isClosed() && _poly.numVerts() > 2) { AcGePoint2d _pt; _poly.getPointAt(0, _pt); poly->addVertexAt(poly->numVerts(), _pt); } AecDbXWall *pWall(NULL); AecDbColumn *pColumn(NULL); AecDbBeam *pBeam(NULL); AecDbXSlab *pSlab(NULL); AcGePoint2dArray arPts(0); AcGePoint2d pt1, pt2; for (int i = 0; i < poly->numVerts() - 1; ++i) { poly->getPointAt(i, pt1); poly->getPointAt(i + 1, pt2); // 墙 { pWall = new AecDbXWall(); pWall->SetBaseCurve(CoreTools::asAcGePoint3d(pt1), CoreTools::asAcGePoint3d(pt2)); pWall->SetWallData(dInnerT, dWallH, dElevWall); pWall->transformBy(mat); arEnts.append(pWall); } if (bColumn) { pColumn = new AecDbColumn(); pColumn->SetPosition(CoreTools::asAcGePoint3d(pt1, dElevColumn)); pColumn->SetHeight(dColumnH); pColumn->SetRect(dColumnL, dColumnW); pColumn->transformBy(mat); arEnts.append(pColumn); } if (bBeam) { pBeam = new AecDbBeam(); pBeam->SetBaseCurve(CoreTools::asAcGePoint3d(pt1, dBeamElev) , CoreTools::asAcGePoint3d(pt2, dBeamElev)); pBeam->SetBeamData(dBeamW, dBeamT); pBeam->transformBy(mat); arEnts.append(pBeam); } } poly->transformBy(mat); for (int i = 0; i < poly->numVerts(); ++i) { poly->getPointAt(i, pt1); arPts.append(pt1); } AcDbExtents ext; poly->getGeomExtents(ext); // 板 if (!arPts.isEmpty()) { pSlab = new AecDbXSlab(); pSlab->SetRegionSlab(arPts, dSlabT, dSlabElev, CoreTools::MidPt(ext.maxPoint(), ext.minPoint())); //pSlab->transformBy(mat); arEnts.append(pSlab); } DELETE_PTR(poly); } void AcDbPolyline2GePolygon2d(const AcDbPolyline &poly, Geometry::GePwh2d &pwh) { pwh.outer_boundary.vertexs.clear(); pwh.inner_holes.clear(); AcGePoint2d pt(AcGePoint2d::kOrigin); for (int i = 0; i < poly.numVerts(); ++i) { poly.getPointAt(i, pt); pwh.outer_boundary.vertexs.push_back(pt); } if (!Geometry::is_counterclockwise(pwh)) { std::reverse(pwh.outer_boundary.vertexs.begin(), pwh.outer_boundary.vertexs.end()); } } /* 两个四边形相交(A,B),考虑四种情况 如果相交,则A与B的差最少为三边形,最多为四边形 其中,有两点构成一条相交线L 由另一点或两点,向L做垂线k,则k长度最长的为要移动的距离,k为移动方向 */ void rearrangePolygon(std::vector &polys) { // 为加快速度, 这里只操作内存 AcGeMatrix3d mat3d; AcGeVector3d vt3d; Geometry::GePwh2d P, Q; Geometry::GePwh2dList lst; for (size_t i = 0; i < polys.size(); ++i) { AcDbPolyline *poly1(polys[i]); AcDbPolyline2GePolygon2d(*poly1, P); for (size_t j = 0; j < polys.size(); j++) { AcDbPolyline *poly2(polys[j]); if ((DWORD_PTR)poly1 == (DWORD_PTR)poly2) continue; AcDbPolyline2GePolygon2d(*poly2, Q); if (!Geometry::is_intersect(P, Q)) continue; // 不相交 lst.clear(); Geometry::intersect(P, Q, lst); if (lst.size() != 1) continue; // 简单无洞多边形,只交出一个多边形 Geometry::GePwh2d &pwh(lst[0]); // 先找到交线 // 交线的是特征是:组成交线的两个点,即在P上,又在Q上 AcGePoint2dArray arOn, arIn; for (size_t k = 0; k < pwh.outer_boundary.vertexs.size(); ++k) { AcGePoint2d &pt(pwh.outer_boundary.vertexs[k]); Geometry::Bounded_side p = Geometry::boundary_check(pt, P); Geometry::Bounded_side q = Geometry::boundary_check(pt, Q); // 属于P的节点,又在Q上 if (p == Geometry::eIsPoint && q == Geometry::eOnside) arOn.append(pt); // 即在P上,又在Q上,但不属于两者节点 else if (p == Geometry::eOnside && q == Geometry::eOnside) arOn.append(pt); else arIn.append(pt); } if (arOn.length() != 2 || arIn.isEmpty()) continue; AcGeLineSeg2d seg(arOn[0], arOn[1]); // 取出距交线最远的点 AcGePoint2d ptIn, ptOn, ptInTemp, ptOnTemp; double dist(.0), dTemp(.0); for (size_t m = 0; m < arIn.length(); ++m) { ptInTemp = arIn[m]; ptOnTemp = seg.closestPointTo(ptInTemp); dTemp = ptInTemp.distanceTo(ptOnTemp); if (dTemp > dist) { dist = dTemp; ptOn = ptOnTemp; ptIn = ptInTemp; } } vt3d = CoreTools::asAcGePoint3d(ptIn) - CoreTools::asAcGePoint3d(ptOn); Geometry::Bounded_side p = Geometry::boundary_check(ptIn, P); if (p == Geometry::eInside || p == Geometry::eOnside) vt3d *= -1; mat3d.setToTranslation(vt3d); poly2->transformBy(mat3d); } } } struct compare_dbpoly { bool operator() (AcDbPolyline *p1, AcDbPolyline *p2) { AcDbExtents ext; p1->getGeomExtents(ext); AcGePoint2d pt1(CoreTools::MidPt(ext.maxPoint(), ext.minPoint()).convert2d(AcGePlane::kXYPlane)); p2->getGeomExtents(ext); AcGePoint2d pt2(CoreTools::MidPt(ext.maxPoint(), ext.minPoint()).convert2d(AcGePlane::kXYPlane)); double delta = pt1.y - pt2.y; if (EQUAL_ZERO(delta)) return pt1.x < pt2.x; else return pt1.y < pt2.y; } }; } IMPLEMENT_DYNAMIC(CPMSCDlg, CDialog) CPMSCDlg::CPMSCDlg(CWnd* pParent /*=nullptr*/) : CDialog(IDD_DLG_PMSC, pParent) , m_dEle(.0) , m_dSlabThickness(200) , m_dOuterWallThickness(200) , m_dInnerWallThickness(200) , m_iHasColumn(0) , m_iHasBeam(0) , m_dColumnW(200) , m_dColumnL(200) , m_dBeamThickness(500) , m_dBeamW(200) { GET_CACHE(CPMSCDlg , %f%f%f%f%d%d%f%f%f%f , &m_dEle , &m_dSlabThickness , &m_dOuterWallThickness , &m_dInnerWallThickness , &m_iHasColumn , &m_iHasBeam , &m_dColumnW , &m_dColumnL , &m_dBeamThickness , &m_dBeamW ); } CPMSCDlg::~CPMSCDlg() { } void CPMSCDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT1, m_dEle); DDX_Text(pDX, IDC_EDIT2, m_dSlabThickness); DDV_MinMaxDouble(pDX, m_dSlabThickness, 0.1, 9999999); DDX_Text(pDX, IDC_EDIT3, m_dOuterWallThickness); DDV_MinMaxDouble(pDX, m_dOuterWallThickness, 0.1, 99999999); DDX_Text(pDX, IDC_EDIT12, m_dInnerWallThickness); DDV_MinMaxDouble(pDX, m_dInnerWallThickness, 0.1, 9999999); DDX_Check(pDX, IDC_CHECK1, m_iHasColumn); DDX_Check(pDX, IDC_CHECK2, m_iHasBeam); DDX_Text(pDX, IDC_EDIT18, m_dColumnL); DDX_Text(pDX, IDC_EDIT6, m_dColumnW); DDX_Text(pDX, IDC_EDIT4, m_dBeamThickness); DDV_MinMaxDouble(pDX, m_dBeamThickness, 0.1, 9999999); DDX_Text(pDX, IDC_EDIT5, m_dBeamW); } BOOL CPMSCDlg::OnInitDialog() { CDialog::OnInitDialog(); UpdateData(FALSE); refreshUI(); return TRUE; } void CPMSCDlg::refreshUI() { UpdateData(TRUE); CWnd *pWnd(NULL); pWnd = GetDlgItem(IDC_EDIT18); if (pWnd) pWnd->EnableWindow(m_iHasColumn); pWnd = GetDlgItem(IDC_EDIT6); if (pWnd) pWnd->EnableWindow(m_iHasColumn); pWnd = GetDlgItem(IDC_EDIT4); if (pWnd) pWnd->EnableWindow(m_iHasBeam); pWnd = GetDlgItem(IDC_EDIT5); if (pWnd) pWnd->EnableWindow(m_iHasBeam); } BEGIN_MESSAGE_MAP(CPMSCDlg, CDialog) ON_BN_CLICKED(IDOK, &CPMSCDlg::OnBnClickedOk) ON_BN_CLICKED(IDC_CHECK1, &CPMSCDlg::refreshUI) ON_BN_CLICKED(IDC_CHECK2, &CPMSCDlg::refreshUI) END_MESSAGE_MAP() void CPMSCDlg::OnBnClickedOk() { UpdateData(TRUE); SET_CACHE(CPMSCDlg , %f%f%f%f%d%d%f%f%f%f , m_dEle , m_dSlabThickness , m_dOuterWallThickness , m_dInnerWallThickness , m_iHasColumn , m_iHasBeam , m_dColumnW , m_dColumnL , m_dBeamThickness , m_dBeamW ); CDialog::OnOK(); } void CPMSCDlg::start() { /* ads_name ss; struct resbuf* pRb = acutBuildList(RTDXF0, _T("LWPOLYLINE"), 0); if (CKTCadUtility::SelectEntities(_T("请选择对象:"), ss, pRb) != RTNORM) { acutRelRb(pRb); return; } acutRelRb(pRb); ads_name ent; AcDbObjectId id(AcDbObjectId::kNull); Adesk::Int32 count(0); acedSSLength(ss, &count); Geometry::GePwh2dList pwhlst(0); Geometry::GePwh2d pwh; for (long i = 0; i < count; ++i) { acedSSName(ss, i, ent); if (acdbGetObjectId(id, ent) != Acad::eOk) continue; OPENOBJ_BEGIN(id, AcDb::kForRead, AcDbPolyline, pPoly) { if (!pPoly) continue; pwh.inner_holes.clear(); pwh.outer_boundary.vertexs.clear(); AcDbPolyline2GePolygon2d(*pPoly, pwh); pwhlst.push_back(pwh); } OPENOBJ_END() } ads_ssfree(ss); //rearrangePolygon(pwhlst); for (size_t i = 0; i < pwhlst.size(); ++i) { Geometry::GePwh2d &pwh(pwhlst[i]); AcDbPolyline *p = new AcDbPolyline(); for (size_t j = 0; j < pwh.outer_boundary.vertexs.size(); j++) { p->addVertexAt(j, pwh.outer_boundary.vertexs[j]); p->setColorIndex(1); } p->setClosed(1); CoreTools::AddToModelSpace(p); } return;*/ CAcModuleResourceOverride myResources; CPMSCDlg dlg; if (dlg.DoModal() != IDOK) return; AcAxDocLock lock; CGLTKDlg TKDlg(CGLTKDlg::eSelect, _T("poolstandard.db"), _T("poolcell"), CGLTKDlg::drawPoolCell); if (TKDlg.DoModal() != IDOK) return; CString script(_T("")); TKDlg.GetCrossSectionScr(script); if (script.IsEmpty()) return; AcGePoint3d ptOrg(AcGePoint3d::kOrigin); std::vector vec(0); CPMSJDlg::generateCellsByString(script, vec, ptOrg); ads_point adsPt; if (ads_getpoint(NULL, _T(""), adsPt) != RTNORM) return; AcGePoint3d ptIns(asPnt3d(adsPt)); CoreTools::UCS2WCS(ptIns, ptIns); AcGeVector3d vt(ptIns - ptOrg); AcGeMatrix3d mat; mat.setTranslation(vt); if (vec.empty()) { acutPrintf(_T("\n解析水池脚本失败!")); return; } double dElevWall(dlg.m_dEle) , dElevColumn(dlg.m_dEle) , dInnerT(dlg.m_dInnerWallThickness) , dOuterT(dlg.m_dOuterWallThickness) , dSlabT(dlg.m_dSlabThickness) , dSlabElev(dlg.m_dEle) , dColumnL(dlg.m_dColumnL) , dColumnW(dlg.m_dColumnW) , dBeamT(dlg.m_dBeamThickness) , dBeamW(dlg.m_dBeamW); if (EQUAL_ZERO(dColumnL)) dColumnL = dInnerT; if (EQUAL_ZERO(dColumnW)) dColumnW = dInnerT; if (EQUAL_ZERO(dBeamW)) dBeamW = dInnerT; bool bColumn(dlg.m_iHasColumn == 0 ? false : true) , bBeam(dlg.m_iHasBeam == 0 ? false : true); AcDbPolyline *pPL(NULL); std::map cells; std::vector polys; for (size_t i = 0; i < vec.size(); ++i) { pPL = new AcDbPolyline(); AecDbPoolCell *pCell(vec[i]); pCell->GetSimplyPoolCell(pPL, dInnerT); cells.insert(std::make_pair(pCell, pPL)); polys.push_back(pPL); } std::sort(polys.begin(), polys.end(), compare_dbpoly()); //for (int i = 0; i < polys.size(); ++i) // CoreTools::AddToModelSpace((AcDbEntity*)polys[i]->clone()); rearrangePolygon(polys); //for (int i = 0; i < polys.size(); ++i) //{ // AcDbEntity *p((AcDbEntity*)polys[i]->clone()); // p->setColorIndex(1); // CoreTools::AddToModelSpace(p); //} std::map::const_iterator it(cells.begin()); AcDbVoidPtrArray arEnts(0); for (; it != cells.end(); ++it) { const AecDbPoolCell *pCell(it->first); double dWallH(pCell->GetH() + dSlabT); if (bBeam) dWallH -= dBeamT; double dColumnH(pCell->GetH() + dSlabT); double dBeamElev(dElevWall + dWallH + dBeamT * .5); generateBuilding(arEnts , bColumn , bBeam , mat , *(it->second) , dInnerT , dWallH , dElevWall , dSlabT , dSlabElev , dColumnH , dColumnL , dColumnW , dElevColumn , dBeamW , dBeamT , dBeamElev); } for (int i = 0; i < arEnts.length(); ++i) CoreTools::AddToModelSpace((AcDbEntity*)arEnts[i]); deleteContainerOfStd(polys); deleteContainerOfStd(vec); }