Files
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

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);
}