484 lines
12 KiB
C++
484 lines
12 KiB
C++
#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 <algorithm>
|
|
#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<AcDbPolyline*> &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<AecDbPoolCell*> 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<AecDbPoolCell *, AcDbPolyline *> cells;
|
|
std::vector<AcDbPolyline*> 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<AecDbPoolCell *, AcDbPolyline *>::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);
|
|
}
|
|
|