Files
envi-code/SourceCode/Code2026/Dimension/HorizontalSection.cpp
T
2026-09-28 15:28:50 +08:00

354 lines
8.1 KiB
C++

#include "StdAfx.h"
#include "TSectionEdJig.h"
#include <map>
#include "dbxutil.h"
#include "globalFunc.h"
#include "RBList.h"
#include "ImpDrawGeneralSection.h"
#include "ImpDrawControllableSection.h"
#include "HorizontalSectionDlg.h"
#include "gearc3d.h"
#include "PickEntSet.h"
//***************************************************************************************************
// 横断面图
//***************************************************************************************************
static void FreeBuffer(int n, AcDbVoidPtrArray& arEntPtrs)
{
AcDbEntity* pEnt = NULL;
while (arEntPtrs.length() > n)
{
pEnt = (AcDbEntity*)arEntPtrs.last();
if (pEnt != NULL)
{
pEnt->erase();
pEnt->close();
arEntPtrs.removeLast();
if (pEnt)
delete pEnt;
}
}
}
AcDbArc* FormatArc(const AcGePoint3d& ptGe1, const AcGePoint3d& ptGe2, const AcGePoint3d& ptGe3)
{
AcDbArc* pArcThis = NULL;
AcGeCircArc3d cirArc3d;
cirArc3d.set(ptGe1, ptGe2, ptGe3);
AcGeVector3d vtNorm = cirArc3d.normal();
if (vtNorm.isParallelTo(AcGeVector3d::kZAxis))
{
if (!vtNorm.isCodirectionalTo(AcGeVector3d::kZAxis))
{
vtNorm.negate();//相反
}
}
AcDbCircle cir;
cir.setCenter(cirArc3d.center());
cir.setRadius(cirArc3d.radius());
cir.setNormal(vtNorm);
AcGePoint3dArray arPts;
arPts.append(ptGe1);
arPts.append(ptGe3);
AcDbVoidPtrArray arCurPtrs;
cir.getSplitCurves(arPts, arCurPtrs);
double dPara = 0.0;
AcDbCurve* pCurve = NULL;
for (int j = 0; j < arCurPtrs.length(); j++)
{
pCurve = (AcDbCurve*)arCurPtrs.at(j);
if (pCurve != NULL)
{
if (Acad::eOk == pCurve->getParamAtPoint(ptGe2, dPara))//中点在圆弧上
{
AcDbArc* pArc = AcDbArc::cast(pCurve);
if (pArc != NULL)
{
pArcThis = pArc;
arCurPtrs.removeAt(j);
}
break;
}
}
}
FreeBuffer(0, arCurPtrs);
return pArcThis;
}
// 剖切线与道路中心线相交
bool CheckMidLine(const AcDbObjectId idLine, const AcGePoint3d &pt1, const AcGePoint3d &pt2)
{
// 求剖切线与道路中线的交点
AcDbEntity *pEnt = NULL;
acdbOpenObject(pEnt, idLine, AcDb::kForRead);
if (pEnt == NULL)
{
return false;
}
AcDbArc *pArc = AcDbArc::cast(pEnt);
AcDbLine *pLine = AcDbLine::cast(pEnt);
AcDbPolyline *pPoly = AcDbPolyline::cast(pEnt);
AcGePoint3d ptS = pt1, ptE = pt2;
ptS.z = 0.0;
ptE.z = 0.0;
AcDbLine line(ptS, ptE);
AcGePoint3dArray arPt;
if (pLine != NULL)
{
AcGePoint3d pt1, pt2;
pt1 = pLine->startPoint();
pt2 = pLine->endPoint();
pEnt->close();
pt1.z = 0.0;
pt2.z = 0.0;
AcDbLine line2(pt1, pt2);
line2.intersectWith(&line, AcDb::kExtendBoth, arPt);
}
else if (pArc != NULL)
{
double dRadius = pArc->radius();
double dStartAngle = pArc->startAngle();
double dEndAngle = pArc->endAngle();
AcGePoint3d ptCenter = pArc->center();
pEnt->close();
ptCenter.z = 0.0;
AcDbArc arc(ptCenter, dRadius, dStartAngle, dEndAngle);
arc.intersectWith(&line, AcDb::kExtendBoth, arPt);
}
else if (pPoly != NULL)
{
AcDbPolyline poly;
AcGePoint2d pt;
for (int i = 0; i < pPoly->numVerts(); i++)
{
pPoly->getPointAt(i, pt);
poly.addVertexAt(i, pt);
}
pEnt->close();
poly.intersectWith(&line, AcDb::kExtendBoth, arPt);
}
else
{
CString sClassName = pEnt->isA()->name();
if (sClassName.CompareNoCase(_T("AecDb3dRoad")) == 0)
{
AcDbCurve* pRoad = AcDbCurve::cast(pEnt);
if (pRoad != NULL)
{
AcGePoint3d ptSta, ptEnd;
pRoad->getStartPoint(ptSta);
pRoad->getEndPoint(ptEnd);
double dSta = 0.0, dEnd = 0.0;
pRoad->getStartParam(dSta);
pRoad->getEndParam(dEnd);
AcGeVector3d vtDir = ptEnd - ptSta;
vtDir.normalize();
AcGePoint3d ptMid;
pRoad->getPointAtParam((dSta + dEnd) / 2.0, ptMid);
AcGeVector3d vtMid = ptMid - ptEnd;
if (vtMid.isParallelTo(vtDir))//LINE
{
ptSta.z = 0.0;
ptEnd.z = 0.0;
AcDbLine line2(ptSta, ptEnd);
line2.intersectWith(&line, AcDb::kExtendBoth, arPt);
}
else//ARC
{
ptSta.z = 0.0;
ptEnd.z = 0.0;
ptMid.z = 0.0;
AcDbArc* pArc = FormatArc(ptSta, ptMid, ptEnd);
if (pArc != NULL)
{
pArc->intersectWith(&line, AcDb::kExtendBoth, arPt);
delete pArc;
}
}
}
}
else
{
return false;
}
}
if (arPt.length() != 1)
{
return false;
}
return true;
}
// cet 2010.4.19 add
void HorizontalSection()
{
// 剖切管线
PickSet ssComps(SS_FREE);
GlobalFunc::DocGetPickFirst().Free();
AcGeVector3d vecView, vt3d;
TSectionEdJig secJig;
secJig.SymbSection();
secJig.GetPickset(ssComps);
// 剖切点
XPoint pt1 = secJig.GetSecPoint();
XPoint pt2 = secJig.GetSecPoint2();
//剖切编号
CString strNumber = secJig.GetNumber();
vecView = secJig.GetSecDir(); // 剖切方向
pt1.z = 0;
vecView.normalize();
// 选择道路中心线
int nRet = 0;
RBList rbMask(RTDXF0, _T("LINE,LWPOLYLINE,ARC,AEC_3DROAD"), 8, _T("*"), NULL);
Entity ent;
nRet = GlobalFunc::SelectEntity(_T("\n请选择道路中心线:<简单绘制>"), ent, rbMask);
if (nRet == RTNORM)
{
AcDbObjectId idLine;
acdbGetObjectId(idLine, ent);
if (!CheckMidLine(idLine, pt1, pt2))
{
ads_printf(_T("\n道路中心线选择不当!"));
return;
}
// 获取与剖切线相交的管线
std::vector<AcDbObjectId> vecId;
for (long i = 0; i < ssComps.Length(); i++)
{
Entity ent = ssComps[i];
if (ent.Is(_T("AEC_ZT_PIPE")))
{
AcDbObjectId id1 = AcDbObjectId::kNull;
acdbGetObjectId(id1, ent);
vecId.push_back(id1);
}
}
CTemporaryResourceOverride vTemp;
CHorizontalSectionDlg dlg;
dlg.SetRoadMidLineId(idLine);
dlg.SetVt(vecView);
dlg.SetPtS(pt1);
dlg.SetPtE(pt2);
dlg.SetPipesId(vecId);
dlg.SetNumber(strNumber);
if (dlg.DoModal() == IDCANCEL)
{
return;
}
double dCarWidth = dlg.GetCarWidth();
double dCarGrad = dlg.GetCarGrad();
double dNoCarWidth = dlg.GetNoCarWidth();
double dNoCarGrad = dlg.GetNoCarGrad();
double dMenWidth = dlg.GetMenWidth();
double dMenGrad = dlg.GetMenGrad();
double dGreenWidth1 = dlg.GetGreenWidth1();
double dGreenGrad1 = dlg.GetGreenGrad1();
double dGreenWidth2 = dlg.GetGreenWidth1();
double dGreenGrad2 = dlg.GetGreenGrad1();
double dScaleX = dlg.GetScaleX();
double dScaleY = dlg.GetScaleY();
double dHeight1 = dlg.GetHeight1();
double dHeight2 = dlg.GetHeight2();
double dRoadEle = dlg.GetRoadEle();
int nRoadType = dlg.GetRoadType();
CImpDrawControllableSection Section;
Section.SetRoadMidEle(dRoadEle);
Section.SetRoadMidLineId(idLine);
Section.SetIdPipe(vecId);
Section.SetVt(vecView);
Section.SetPtS(pt1);
Section.SetPtE(pt2);;
Section.SetNumber(strNumber);
Section.SetScaleX(dScaleX);
Section.SetScaleY(dScaleY);
Section.SetCarGrad(dCarGrad);
Section.SetCarWidth(dCarWidth);
Section.SetMenGrad(dMenGrad);
Section.SetMenWidth(dMenWidth);
Section.SetNoCarGrad(dNoCarGrad);
Section.SetNoCarWidth(dNoCarWidth);
Section.SetGreenGrad(dGreenGrad1);
Section.SetGreenWidth(dGreenWidth1);
Section.SetGreenGrad2(dGreenGrad2);
Section.SetGreenWidth2(dGreenWidth2);
Section.SetMenHeight(dHeight1);
Section.SetSplitHeight(dHeight2);
Section.SetType(nRoadType);
Section.DrawSection();
}
else
{
double dRoadEle = 0.0;
if (acedGetReal(_T("\n请输入道路标高(m)<退出>:"), &dRoadEle) != RTNORM)
{
return;
}
double dScaleX = 0.0;
int nRet = -1;
if (acedGetReal(_T("\n横断面图横向比例<100>:"), &dScaleX) != RTNORM)
{
dScaleX = 100;
}
double dScaleY = 0.0;
if (acedGetReal(_T("\n横断面图横向比例<50>:"), &dScaleY) != RTNORM)
{
dScaleY = 50;
}
// 获取与剖切线相交的管线
std::vector<AcDbObjectId> vecId;
for (long i = 0; i < ssComps.Length(); i++)
{
Entity ent = ssComps[i];
if (ent.Is(_T("AEC_ZT_PIPE")))
{
AcDbObjectId id1 = AcDbObjectId::kNull;
acdbGetObjectId(id1, ent);
vecId.push_back(id1);
}
}
CImpDrawGeneralSection GeneralSection;
double dRoadWidth = ads_distance(pt1, pt2);
GeneralSection.SetRoadMidEle(dRoadEle);
GeneralSection.SetIdPipe(vecId);
GeneralSection.SetVt(vecView);
GeneralSection.SetPtS(pt1);
GeneralSection.SetPtE(pt2);;
GeneralSection.SetNumber(strNumber);
GeneralSection.SetScaleX(dScaleX);
GeneralSection.SetScaleY(dScaleY);
GeneralSection.DrawSection();
}
}