Files
envi-code/SourceCode/Code2026/tg_shs/shs_kerncmd/DLWDMain.cpp
T

1368 lines
38 KiB
C++
Raw Normal View History

2026-09-28 15:28:50 +08:00
#include "StdAfx.h"
#include "dlwdmain.h"
//#include "afxdialogex.h"
#include "dbray.h"
#include "dbelipse.h"
static TBuildInfomationDlg *g_pDlg = NULL;
static AcDbObjectId g_idBuild = AcDbObjectId::kNull;
static AcDbObjectId g_idLight = AcDbObjectId::kNull;
namespace
{
void Poly2Building(AcDbObjectId id, const double lastH, const double elevH, LPCTSTR slayer)
{
ads_name name;
if (Acad::eOk != acdbGetAdsName(name, id)) return;
TEntitySet e(name);
PickSet ss(SS_FREE);
ss += e;
Entity entFirst = ss[0L];
double nElev(elevH), nHeight(lastH);
double nLastHeight = _AS_MM(nHeight);
Entity ent = ss[0L];
XPoint vtNorm(0, 0, 1);
ent.GetData(210, vtNorm);
if (vtNorm.AsAcGeVector3d() != AcGeVector3d(0, 0, 1))
{
adsout << _T("\n发现pline法向无效!");
return;
}
XPoly2D poly2d(ent);
poly2d.SetFlag(1);//强制封闭,add by whl on 060418
poly2d.Compress();
if (poly2d.IsSelfIntersect())
{
adsout << _T("\n发现自交的无效pline!");
return;
}
if (poly2d.PathArea() > 0.0)
poly2d.Reverse();
TDbSlab *pSlab = new TDbSlab;
pSlab->SetOutline(poly2d);
pSlab->SetElevation(nElev);
pSlab->SetThickness(nHeight);
pSlab->setLayer(slayer);
AcDbObjectId idNew = AddToModelSpace(pSlab, Adesk::kTrue);
}
int FindCloseLine(const std::vector<AcGeLineSeg3d> &lines, LPCTSTR str)
{
XPushVar<int> osmode(_T("OSMODE"), 0);
XPoint point;
double dist(.0);
std::map<double, int> lmap;
while (true)
{
lmap.clear();
int ret = acedGetPoint(NULL, str, point);
if (ret != RTNORM) return -1;
AcGePoint3d acgePt(point.x, point.y, point.z);
for (int i = 0; i < lines.size(); ++i)
lmap.insert(std::make_pair(lines[i].distanceTo(acgePt), i));
if (lmap.size() < lines.size()) // 说明与其它边的distance相同,重选
{
acutPrintf(_T("\n请重新选择!"));
continue;
}
return lmap.begin()->second;
}
}
void InsertText(LPCTSTR strText, const AcGePoint3d &ptDefault, const AcGeVector3d &vec)
{
XPoint point;
TDbText *pTextLabel = new TDbText();
pTextLabel->SetAlignment(XExplodeDraw::kLeft);
pTextLabel->SetPScale(1);
pTextLabel->SetStyleId(GetTextStyleId(_T("黑体")));
pTextLabel->SetHeight(9.11);
pTextLabel->SetLocation(ptDefault);
pTextLabel->SetText(strText);
pTextLabel->SetRotation(atan(vec.y/vec.x));
pTextLabel->setLayer(_T("总图-字体"));
AddToCurrentSpace(pTextLabel, Adesk::kTrue);
}
AcDbObjectId CreateHatchForObj(AcDbObjectIdArray &ids)
{
AcDbHatch *pHatch = new AcDbHatch;
Acad::ErrorStatus es =pHatch->setHatchObjectType(AcDbHatch::kHatchObject);
es = pHatch->setNormal(AcGeVector3d(0, 0, 1));
es = pHatch->setElevation(0.0);
es = pHatch->setAssociative(Adesk::kFalse);
es = pHatch->setHatchStyle(AcDbHatch::kNormal);
es = pHatch->setColorIndex(140);
es = pHatch->setPatternAngle(0.0);
es = pHatch->setPatternScale(1/*DocGetPScale()*/);
es = pHatch->setPattern(AcDbHatch::kPreDefined, _T("NET3"));
es = pHatch->insertLoopAt(0, AcDbHatch::kExternal, ids);
es = pHatch->evaluateHatch();
return AddToCurrentSpace(pHatch, Adesk::kTrue);
}
int Dim2Pt(XPoint ptLeft, XPoint ptRight)
{
if (ptRight.Distance2d(ptLeft) < _DIST_SNAP)
{
return FALSE;
}
TDbDimension2 *pDim = new TDbDimension2;
pDim->SetPScale(1);
pDim->SetLayoutRotation(Ucs2Wcs(0));//add by whl on 060306
pDim->SetLocation(ptLeft);
pDim->SetRotation(ads_angle(ptLeft, ptRight));
pDim->SetDist2DimLine(6.0, TRUE);
pDim->AppendSegment(ptLeft.Distance2d(ptRight));
AcDbObjectId idStyle = InitDimStyle(DS_LINEAR);
pDim->SetStyleId(idStyle);
AcGiTextStyle txtStyle;
OPENOBJ_BEGIN(idStyle, AcDb::kForRead, AcDbDimStyleTableRecord, pStyle);
ASSERT(pStyle);
VERIFY(fromAcDbTextStyle(txtStyle, pStyle->dimtxsty()) == Acad::eOk);
int nRetFlag = txtStyle.loadStyleRec();
txtStyle.setTextSize(pStyle->dimtxt()*pDim->GetPScale()*0.8);
OPENOBJ_END();
ads_real rHWidth = ads_distance(ptLeft, ptRight) / 2, rAngle = ads_angle(ptLeft, ptRight); //移动方向
AcGePoint2d ptExt = txtStyle.extents(pDim->GetText(0), Adesk::kTrue, -1, Adesk::kTrue);
rHWidth += ptExt[0] / 2 + 1.0*pDim->GetPScale();
XVector3D vtMove(rHWidth*cos(rAngle), rHWidth*sin(rAngle));
XPoint ptText = pDim->GetTextPos(0);
ptText += vtMove;
//pDim->SetTextPos(0, ptText);
pDim->SetLayoutRotation(Ucs2Wcs(0.0));
pDim->setLayer(_T("总图-尺寸标注"));
AddToModelSpace(pDim);
return RTNORM;
}
void DrawCircle(AcGePoint3d pt, int idxcolor = -1)
{
AcDbCircle *pCir = new AcDbCircle(pt, AcGeVector3d::kZAxis, 1);
if (idxcolor != -1)
pCir->setColorIndex(idxcolor);
AddToModelSpace(pCir);
}
void DrawLine(AcGeLineSeg3d line, int idxcolor = -1)
{
AcDbLine *pL = new AcDbLine(line.startPoint(), line.endPoint());
if (idxcolor != -1)
pL->setColorIndex(idxcolor);
AddToModelSpace(pL);
}
AcDbObjectId Insert2MSpace(TGGePoly3D &poly, LPCTSTR slayer)
{
AcDbObjectId id(AcDbObjectId::kNull);
AcDbCurve *p(NULL);
AcDbCurve *pC = poly.AsAcDbCurve();
pC->getOrthoProjectedCurve(AcGePlane::kXYPlane, p);
if (p)
{
p->setLayer(slayer);
id = AddToModelSpace(p);
}
delete pC;
return id;
}
}
void WD()
{
if (g_pDlg)
{
g_pDlg->DestroyWindow();
g_pDlg = NULL;
}
else
{
CAcModuleResourceOverride res;
g_pDlg = new TBuildInfomationDlg;
g_pDlg->Create(IDD_DIALOG_DLWD, (CWnd*)acedGetAcadFrame());
g_pDlg->ShowWindow(SW_SHOW);
g_pDlg->CenterWindow();
}
}
void WDLG()
{
if (!g_idBuild.isValid() || !g_idLight.isValid()) return;
Poly2Building(g_idBuild, 15.9, 0., _T("总图-建筑轮廓线"));
Poly2Building(g_idLight, 26.1, 0., _T("轻资产"));
acedPostCommand(_T("-view _swiso "));
acedPostCommand(_T("_SHADEMODE r "));
};
// dlwdmain.cpp : implementation file
//////////////////////////////////////////////////////////////////////////
namespace
{
void EnableCtrl(CDialog *pDlg, int resid, BOOL bDisable)
{
if (!pDlg) return;
CWnd *pWnd = pDlg->GetDlgItem(resid);
if (!pWnd) return;
pWnd->EnableWindow(bDisable);
}
void VisableCtrl(CDialog *pDlg, int resid, int nshow)
{
if (!pDlg) return;
CWnd *pWnd = pDlg->GetDlgItem(resid);
if (!pWnd) return;
pWnd->ShowWindow(nshow);
}
}
IMPLEMENT_DYNAMIC(TBuildInfomationDlg, CModelessDialog)
TBuildInfomationDlg::TBuildInfomationDlg(CWnd* pParent /*=NULL*/)
: CModelessDialog(TBuildInfomationDlg::IDD, pParent) { }
TBuildInfomationDlg::~TBuildInfomationDlg()
{
RemoveColorLine();
}
void TBuildInfomationDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT_UP_AOTO, m_redline.m_nUpAtuoNum);
DDV_MinMaxInt(pDX, m_redline.m_nUpAtuoNum, 0, 100000);
DDX_Text(pDX, IDC_EDIT_UP_BIKE, m_redline.m_nUpBikeNum);
DDV_MinMaxInt(pDX, m_redline.m_nUpBikeNum, 0, 100000);
DDX_Text(pDX, IDC_EDIT_GREEN_RATIO , m_redline.m_dGreen);
DDV_MinMaxDouble(pDX, m_redline.m_dGreen, 0, 100);
DDX_Text(pDX, IDC_EDIT_BUILD_DENSITY, m_redline.m_dBuildDensity);
DDV_MinMaxDouble(pDX, m_redline.m_dBuildDensity, 0, 100);
DDX_Text(pDX, IDC_EDIT_UP_BUILD_AREA, m_redline.m_dUpBuildArea);
DDV_MinMaxDouble(pDX, m_redline.m_dUpBuildArea, 0, 990000000);
DDX_Text(pDX, IDC_EDIT_DOWN_BUILD_AREA, m_redline.m_dDownBuildArea);
DDV_MinMaxDouble(pDX, m_redline.m_dDownBuildArea, 0, 990000000);
DDX_Text(pDX, IDC_EDIT_RED, m_redline.m_dBacklineRed);
DDV_MinMaxDouble(pDX, m_redline.m_dBacklineRed, 0, 1000);
DDX_Text(pDX, IDC_EDIT_YELLOW, m_redline.m_dBacklineYellow);
DDV_MinMaxDouble(pDX, m_redline.m_dBacklineYellow, 0, 1000);
DDX_Text(pDX, IDC_EDIT_GREEN, m_redline.m_dBacklineGreen);
DDV_MinMaxDouble(pDX, m_redline.m_dBacklineGreen, 0, 1000);
DDX_Text(pDX, IDC_EDIT_CYAN, m_redline.m_dBacklineCyan);
DDV_MinMaxDouble(pDX, m_redline.m_dBacklineCyan, 0, 1000);
DDX_Text(pDX, IDC_EDIT_BLUE, m_redline.m_dBacklineBlue);
DDV_MinMaxDouble(pDX, m_redline.m_dBacklineBlue, 0, 1000);
DDX_Text(pDX, IDC_EDIT_MAGENTA, m_redline.m_dBacklineMagenta);
DDV_MinMaxDouble(pDX, m_redline.m_dBacklineMagenta, 0, 1000);
DDX_Text(pDX, IDC_EDIT_WHITE, m_redline.m_dBacklineWhite);
DDV_MinMaxDouble(pDX, m_redline.m_dBacklineWhite, 0, 1000);
}
BEGIN_MESSAGE_MAP(TBuildInfomationDlg, CModelessDialog)
ON_BN_CLICKED(IDC_BUTTON_SELECT, &TBuildInfomationDlg::OnBnClickedButtonSelect)
ON_BN_CLICKED(IDC_BUTTON_CALC, &TBuildInfomationDlg::OnBnClickedButtonCalc)
ON_WM_CTLCOLOR()
ON_WM_CLOSE()
ON_WM_DESTROY()
ON_EN_CHANGE(IDC_EDIT_UP_AOTO, &TBuildInfomationDlg::OnEnKillfocusEdit)
ON_EN_CHANGE(IDC_EDIT_UP_BIKE, &TBuildInfomationDlg::OnEnKillfocusEdit)
ON_EN_CHANGE(IDC_EDIT_GREEN_RATIO, &TBuildInfomationDlg::OnEnKillfocusEdit)
ON_EN_CHANGE(IDC_EDIT_BUILD_DENSITY, &TBuildInfomationDlg::OnEnKillfocusEdit)
ON_EN_CHANGE(IDC_EDIT_UP_BUILD_AREA, &TBuildInfomationDlg::OnEnKillfocusEdit)
ON_EN_CHANGE(IDC_EDIT_DOWN_BUILD_AREA, &TBuildInfomationDlg::OnEnKillfocusEdit)
ON_EN_CHANGE(IDC_EDIT_RED, &TBuildInfomationDlg::OnEnKillfocusEdit)
ON_EN_CHANGE(IDC_EDIT_YELLOW, &TBuildInfomationDlg::OnEnKillfocusEdit)
ON_EN_CHANGE(IDC_EDIT_GREEN, &TBuildInfomationDlg::OnEnKillfocusEdit)
ON_EN_CHANGE(IDC_EDIT_CYAN, &TBuildInfomationDlg::OnEnKillfocusEdit)
ON_EN_CHANGE(IDC_EDIT_BLUE, &TBuildInfomationDlg::OnEnKillfocusEdit)
ON_EN_CHANGE(IDC_EDIT_MAGENTA, &TBuildInfomationDlg::OnEnKillfocusEdit)
ON_EN_CHANGE(IDC_EDIT_WHITE, &TBuildInfomationDlg::OnEnKillfocusEdit)
ON_MESSAGE(WM_ACAD_KEEPFOCUS, &TBuildInfomationDlg::OnAcadKeepFocus)
END_MESSAGE_MAP()
BOOL TBuildInfomationDlg::OnInitDialog()
{
CDialog::OnInitDialog();
SetWindowText(_T("上华软件"));
BeforSelectRedline();
UpdateData(FALSE);
return TRUE;
}
void TBuildInfomationDlg::OnBnClickedButtonSelect()
{
ShowWindow(SW_HIDE);
EnableCtrl(this, IDC_BUTTON_SELECT, FALSE);
RBList mask(RTDXF0, _T("POLYLINE,LWPOLYLINE"), NULL);
XPoint ptPick;
TEntitySet ent;
XPoint point;
AcGeLineSeg3d seg, seg2, seg1;
AcGePoint3d pt, pt1, pt2;
AcDbObjectId id;
TDocLock lock;
long iResult = ent.FilterSelect(_T("\n请选择红线<取消>:"), mask, ptPick);
if (iResult != RTNORM) goto failed;
if (Acad::eOk != acdbGetObjectId(m_redline.m_id, ent)) goto failed;
OPENOBJ_BEGIN(ent, AcDb::kForWrite, AcDbPolyline, pPoly);
{
if (pPoly == NULL || pPoly->numVerts() < 3 || pPoly->numVerts() > 7)
{
AfxMessageBox(_T("请选择大于3并小于8结点的pline线。"));
goto failed;
}
m_redline.m_RedlinePoly.SetAcDbCurve(pPoly);
//把多段线分段保存在List中
AcGeLineSeg3d lineSeg;
for (size_t i = 0; i < pPoly->numVerts(); ++i)
{
if (Acad::eOk == pPoly->getLineSegAt((int)i, lineSeg))
m_redline.m_RedSegs.push_back(lineSeg);
}
//计算面积
if (Acad::eOk != pPoly->getArea(m_redline.m_dRedlineArea))
{
AfxMessageBox(_T("\n取得PLINE线面积失败。"));
goto failed;
}
pPoly->setVisibility(AcDb::kInvisible);
}
OPENOBJ_END();
// 涂颜色
for (size_t i = 0; i < m_redline.m_RedSegs.size(); ++i)
{
if (i > 7) break;
AcDbLine *pLine = new AcDbLine(m_redline.m_RedSegs[i].startPoint(), m_redline.m_RedSegs[i].endPoint());
pLine->setColorIndex((int)(i+1));
m_redline.m_colorLines.push_back(AddToModelSpace(pLine));
}
m_redline.m_idxDirect = FindCloseLine(m_redline.m_RedSegs, _T("\n请选择建筑物方向:"));
if (m_redline.m_idxDirect == -1) goto failed;
seg1 = m_redline.m_RedSegs[m_redline.m_idxDirect];
pt1 = seg1.midPoint();
AcDbCircle *pCir = new AcDbCircle(pt1, AcGeVector3d::kZAxis, seg1.length()*.05);
pCir->setColorIndex(m_redline.m_idxDirect + 1);
m_redline.m_colorLines.push_back(AddToModelSpace(pCir));
//选择建筑物靠近的边
do
{
m_redline.m_idxCloses = FindCloseLine(m_redline.m_RedSegs, _T("\n请选择建筑物靠近的边:"));
if (m_redline.m_idxCloses == -1) return;
seg2 = m_redline.m_RedSegs[m_redline.m_idxCloses];
// 判断选取的两根线是否有交点
if (seg1.intersectWith(seg2, pt) != Adesk::kTrue) // 没有交点,则重选idx2
{
AfxMessageBox(_T("\n请选择相邻的边。"));
continue;
}
break;
} while (true);
// 取出与方向边相邻的另一条边的索引
seg1 = m_redline.m_RedSegs[m_redline.m_idxDirect];
seg2 = m_redline.m_RedSegs[m_redline.m_idxCloses];
for (size_t i = 0; i < m_redline.m_RedSegs.size(); ++i)
{
seg = m_redline.m_RedSegs[i];
if (seg == seg1 || seg == seg2)continue;
if (seg.intersectWith(seg1, pt))
{
m_redline.m_idxOther = (int)i;
break;
}
}
pt2 = seg2.midPoint();
pCir = new AcDbCircle(pt2, AcGeVector3d::kZAxis, seg1.length()*.05);
pCir->setColorIndex(m_redline.m_idxCloses + 1);
m_redline.m_colorLines.push_back(AddToModelSpace(pCir));
AfterSelectRedline();
ShowWindow(SW_SHOW);
return;
failed:
EnableCtrl(this, IDC_BUTTON_SELECT, TRUE);
ShowWindow(SW_SHOW);
m_redline.m_id = AcDbObjectId::kNull;
}
void TBuildInfomationDlg::OnBnClickedButtonCalc()
{
UpdateData(TRUE);
if (!m_redline.m_id.isValid()) return;
TDocLock lock;
OPENOBJ_BEGIN(m_redline.m_id, AcDb::kForWrite, AcDbPolyline, pPoly)
{
if (pPoly)
pPoly->setVisibility(AcDb::kVisible);
}
OPENOBJ_END()
EnableCtrl(this, IDC_BUTTON_SELECT, TRUE);
RemoveColorLine();
UpdateData(TRUE);
m_redline.CalcBackLine();
AcGeLineSeg3d segBLDirect(m_redline.GetBLDirectSeg()),
segBLCloses(m_redline.GetBLClosesSeg()),
segBLOther(m_redline.GetBLOtherSeg());
// 计算出 m_ptCloses 与 m_ptOther 两点
segBLDirect.intersectWith(segBLCloses, m_redline.m_ptCloses);
m_redline.m_ptOther = m_redline.m_ptCloses == segBLDirect.startPoint() ? segBLDirect.endPoint() : segBLDirect.startPoint();
// 计算出 m_vtDirect, m_vtOther, m_vtCloses
m_redline.m_vtDirect = m_redline.m_ptOther - m_redline.m_ptCloses;
m_redline.m_vtCloses = (m_redline.m_ptCloses == segBLCloses.startPoint() ? segBLCloses.endPoint() : segBLCloses.startPoint()) - m_redline.m_ptCloses;
m_redline.m_vtOther = (m_redline.m_ptOther == segBLOther.startPoint() ? segBLOther.endPoint() : segBLOther.startPoint()) - m_redline.m_ptOther;
double dMin = m_redline.CalcNo3Step();
CString strArea(_T(""));
strArea.Format(_T("%.2f万平方米"), (m_redline.m_dUpBuildArea + m_redline.m_dDownBuildArea)*.0001);
GetDlgItem(IDC_STATIC_ALL_AREA)->SetWindowText(strArea);
strArea.Format(_T("%.2f"), m_redline.m_dVolume);
GetDlgItem(IDC_STATIC_VOLUME)->SetWindowText(strArea);
if (dMin > 28000)
{
m_redline.m_b3Floor = true;
GetDlgItem(IDC_STATIC_RESULT)->SetWindowText(_T("采用三层街方案"));
}
else
{
m_redline.m_b3Floor = false;
GetDlgItem(IDC_STATIC_RESULT)->SetWindowText(_T("采用四层街方案"));
}
bool bRel = m_redline.CalcNo4Step();
if (bRel)
m_redline.CalcDim();
AcGePoint3d ptIns;
{// 计算用地面积插入点
AcGeRay3d ray(m_redline.m_ptOther, m_redline.m_vtOther);
for (size_t i = 0; i < m_redline.m_RedSegs.size(); ++i)
{
AcGeLineSeg3d &seg = m_redline.m_RedSegs[i];
if (ray.intersectWith(seg, ptIns))
break;
}
}
CString strText;
strText.Format(_T("用地面积%.2f万平方米,合%.2f亩"), m_redline.m_dRedlineArea*.0001, m_redline.m_dRedlineArea*0.0015);
InsertText(strText, ptIns, m_redline.m_vtDirect);
strText.Format(_T("室内街 %s L=%.2fm"), m_redline.m_b3Floor ? _T("3F") : _T("4F"), m_redline.m_dFootLength);
InsertText(strText, m_redline.m_ptInsertFootDim, m_redline.m_vtDirect);
strText.Format(_T("轻资产(%.0f万+%.0f万)"), m_redline.m_dUpBuildArea*.0001, m_redline.m_dDownBuildArea*.0001);
InsertText(strText, m_redline.m_ptInsertLightDim1, m_redline.m_vtDirect);
strText = _T("5F");
InsertText(strText, m_redline.m_ptInsertLightDim2, m_redline.m_vtDirect);
acedPostCommand(_T("re\n"));
EnableCtrl(this, IDC_BUTTON_CALC, FALSE);
}
void TBuildInfomationDlg::ShowBackLineCtrl()
{
int n = (int)m_redline.m_RedSegs.size();
if (n > 6) //7
{
VisableCtrl(this, IDC_EDIT_WHITE, TRUE);
VisableCtrl(this, IDC_STATIC_WHITE, TRUE);
VisableCtrl(this, IDC_STATIC_WHITE_M, TRUE);
}
if (n > 5) // 6
{
VisableCtrl(this, IDC_EDIT_MAGENTA, TRUE);
VisableCtrl(this, IDC_STATIC_MAGENTA, TRUE);
VisableCtrl(this, IDC_STATIC_MAGENTA_M, TRUE);
}
if (n> 4) // 5
{
VisableCtrl(this, IDC_EDIT_BLUE, TRUE);
VisableCtrl(this, IDC_STATIC_BLUE, TRUE);
VisableCtrl(this, IDC_STATIC_BLUE_M, TRUE);
}
if (n > 3) // 4
{
VisableCtrl(this, IDC_EDIT_CYAN, TRUE);
VisableCtrl(this, IDC_STATIC_CYAN, TRUE);
VisableCtrl(this, IDC_STATIC_CYAN_M, TRUE);
}
if (n > 2) // 3
{
VisableCtrl(this, IDC_EDIT_RED, TRUE);
VisableCtrl(this, IDC_STATIC_RED, TRUE);
VisableCtrl(this, IDC_STATIC_RED_M, TRUE);
VisableCtrl(this, IDC_EDIT_YELLOW, TRUE);
VisableCtrl(this, IDC_STATIC_YELLOW, TRUE);
VisableCtrl(this, IDC_STATIC_YELLOW_M, TRUE);
VisableCtrl(this, IDC_EDIT_GREEN, TRUE);
VisableCtrl(this, IDC_STATIC_GREEN, TRUE);
VisableCtrl(this, IDC_STATIC_GREEN_M, TRUE);
}
}
void TBuildInfomationDlg::OnDestroy()
{
g_pDlg = NULL;
CModelessDialog::OnDestroy();
delete this;
}
void TBuildInfomationDlg::OnClose()
{
acedPostCommand(_T("\33\33"));
DestroyWindow();
}
void TBuildInfomationDlg::BeforSelectRedline()
{
// 没有选中红线之前,所有控件为灰
EnableCtrl(this, IDC_EDIT_UP_AOTO, FALSE);
EnableCtrl(this, IDC_EDIT_UP_BIKE, FALSE);
EnableCtrl(this, IDC_EDIT_GREEN_RATIO, FALSE);
EnableCtrl(this, IDC_EDIT_BUILD_DENSITY, FALSE);
EnableCtrl(this, IDC_EDIT_UP_BUILD_AREA, FALSE);
EnableCtrl(this, IDC_EDIT_DOWN_BUILD_AREA, FALSE);
EnableCtrl(this, IDC_BUTTON_CALC, FALSE);
VisableCtrl(this, IDC_EDIT_RED, FALSE);
VisableCtrl(this, IDC_EDIT_YELLOW, FALSE);
VisableCtrl(this, IDC_EDIT_GREEN, FALSE);
VisableCtrl(this, IDC_EDIT_CYAN, FALSE);
VisableCtrl(this, IDC_EDIT_BLUE, FALSE);
VisableCtrl(this, IDC_EDIT_MAGENTA, FALSE);
VisableCtrl(this, IDC_EDIT_WHITE, FALSE);
VisableCtrl(this, IDC_STATIC_RED, FALSE);
VisableCtrl(this, IDC_STATIC_YELLOW, FALSE);
VisableCtrl(this, IDC_STATIC_GREEN, FALSE);
VisableCtrl(this, IDC_STATIC_CYAN, FALSE);
VisableCtrl(this, IDC_STATIC_BLUE, FALSE);
VisableCtrl(this, IDC_STATIC_MAGENTA, FALSE);
VisableCtrl(this, IDC_STATIC_WHITE, FALSE);
VisableCtrl(this, IDC_STATIC_RED_M, FALSE);
VisableCtrl(this, IDC_STATIC_YELLOW_M, FALSE);
VisableCtrl(this, IDC_STATIC_GREEN_M, FALSE);
VisableCtrl(this, IDC_STATIC_CYAN_M, FALSE);
VisableCtrl(this, IDC_STATIC_BLUE_M, FALSE);
VisableCtrl(this, IDC_STATIC_MAGENTA_M, FALSE);
VisableCtrl(this, IDC_STATIC_WHITE_M, FALSE);
}
void TBuildInfomationDlg::AfterSelectRedline()
{
EnableCtrl(this, IDC_EDIT_UP_AOTO, TRUE);
EnableCtrl(this, IDC_EDIT_UP_BIKE, TRUE);
EnableCtrl(this, IDC_EDIT_GREEN_RATIO, TRUE);
EnableCtrl(this, IDC_EDIT_BUILD_DENSITY, TRUE);
EnableCtrl(this, IDC_EDIT_UP_BUILD_AREA, TRUE);
EnableCtrl(this, IDC_EDIT_DOWN_BUILD_AREA, TRUE);
EnableCtrl(this, IDC_BUTTON_CALC, TRUE);
ShowBackLineCtrl();
}
void TBuildInfomationDlg::RemoveColorLine()
{
TDocLock lock;
for (size_t i = 0; i < m_redline.m_colorLines.size(); ++i)
{
OPENOBJ_BEGIN(m_redline.m_colorLines[i], AcDb::kForWrite, AcDbEntity, pl)
{
if (!pl) continue;
Acad::ErrorStatus es = pl->erase();
}
OPENOBJ_END()
}
}
HBRUSH TBuildInfomationDlg::OnCtlColor(CDC *pDC, CWnd *pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
HWND hwnd = pWnd->GetSafeHwnd();
if (nCtlColor == CTLCOLOR_STATIC || nCtlColor == CTLCOLOR_EDIT)
{
if (hwnd == GetDlgItem(IDC_STATIC_RED)->GetSafeHwnd() ||
hwnd == GetDlgItem(IDC_STATIC_RED_M)->GetSafeHwnd() ||
hwnd == GetDlgItem(IDC_EDIT_RED)->GetSafeHwnd() )
{
pDC->SetTextColor(RGB(255, 0, 0));
}
else if (hwnd == GetDlgItem(IDC_STATIC_YELLOW)->GetSafeHwnd() ||
hwnd == GetDlgItem(IDC_STATIC_YELLOW_M)->GetSafeHwnd() ||
hwnd == GetDlgItem(IDC_EDIT_YELLOW)->GetSafeHwnd() )
{
pDC->SetTextColor(RGB(255, 255, 0));
}
else if (hwnd == GetDlgItem(IDC_STATIC_GREEN)->GetSafeHwnd() ||
hwnd == GetDlgItem(IDC_STATIC_GREEN_M)->GetSafeHwnd() ||
hwnd == GetDlgItem(IDC_EDIT_GREEN)->GetSafeHwnd() )
{
pDC->SetTextColor(RGB(0, 255, 0));
}
else if (hwnd == GetDlgItem(IDC_STATIC_CYAN)->GetSafeHwnd() ||
hwnd == GetDlgItem(IDC_STATIC_CYAN_M)->GetSafeHwnd() ||
hwnd == GetDlgItem(IDC_EDIT_CYAN)->GetSafeHwnd() )
{
pDC->SetTextColor(RGB(0, 255, 255));
}
else if (hwnd == GetDlgItem(IDC_STATIC_BLUE)->GetSafeHwnd() ||
hwnd == GetDlgItem(IDC_STATIC_BLUE_M)->GetSafeHwnd() ||
hwnd == GetDlgItem(IDC_EDIT_BLUE)->GetSafeHwnd() )
{
pDC->SetTextColor(RGB(0, 0, 255));
}
else if (hwnd == GetDlgItem(IDC_STATIC_MAGENTA)->GetSafeHwnd() ||
hwnd == GetDlgItem(IDC_STATIC_MAGENTA_M)->GetSafeHwnd() ||
hwnd == GetDlgItem(IDC_EDIT_MAGENTA)->GetSafeHwnd() )
{
pDC->SetTextColor(RGB(255, 0, 255));
}
else if (hwnd == GetDlgItem(IDC_STATIC_WHITE)->GetSafeHwnd() ||
hwnd == GetDlgItem(IDC_STATIC_WHITE_M)->GetSafeHwnd() ||
hwnd == GetDlgItem(IDC_EDIT_WHITE)->GetSafeHwnd() )
{
pDC->SetTextColor(RGB(255, 255, 255));
}
}
return hbr;
}
void TBuildInfomationDlg::OnEnKillfocusEdit()
{
UpdateData(TRUE);
}
LONG_PTR TBuildInfomationDlg::OnAcadKeepFocus(UINT_PTR, LONG_PTR)
{
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
void TRedLine::CalcBackLine()
{
// 先得出相应位移后的线段
std::vector<AcGeLineSeg3d> segs;
AcGePoint3d ptS(AcGePoint3d::kOrigin), ptE(AcGePoint3d::kOrigin), ptTmp(AcGePoint3d::kOrigin);
AcGeLineSeg3d seg, segnew;
AcGeVector3d vt(AcGeVector3d::kIdentity);
AcGeRay3d ray;
for (size_t i = 0; i < m_RedSegs.size(); ++i)
{
segnew = seg = m_RedSegs[i];
ptS = seg.startPoint(), ptE = seg.endPoint();
vt = ptE - ptS;
vt.normalize();
vt.rotateBy(PI*.5, AcGeVector3d::kZAxis);
vt *= 5; // 稍放长一些,用些来判断是否指向poly内部
// 判断
ptTmp = seg.midPoint();
ptTmp += vt;
if ((ptTmp & m_RedlinePoly) != PR_INSIDE)
vt.rotateBy(PI, AcGeVector3d::kZAxis);
vt.normalize();
vt *= GetBacklineValue((int)i);
segnew.transformBy(vt);
segs.push_back(segnew);
}
AcGeLineSeg3d seg1, seg2;
// 为保证退线线段顺序与红线一至,先把第一段与最后一段求交点。做为退线的第一个点
seg1 = segs[0], seg2 = segs[segs.size() - 1];
seg1.intersectWith(seg2, ptTmp);
m_BacklinePoly.AppendNode(ptTmp);
for (size_t i = 0; i < segs.size(); ++i)
{
seg1 = segs[i];
if (i + 1 < segs.size())
seg2 = segs[i + 1];
else
break;
seg1.intersectWith(seg2, ptTmp);
m_BacklinePoly.AppendNode(ptTmp);
}
m_BacklinePoly.SetClosed();
m_dBackLineArea = m_BacklinePoly.Area();
// if (!DocGetMeterUnitDraw())
// m_dBackLineArea /= 1000000;
TDocLock lock;
Insert2MSpace(m_BacklinePoly, _T("总图-建筑退线"));
}
double TRedLine::GetBacklineValue(const int &idx)
{
if (idx > 7) return .0;
int num = idx + 1;
double dRel(.0);
if (num == 1) dRel = m_dBacklineRed;
else if (num == 2) dRel = m_dBacklineYellow;
else if (num == 3) dRel = m_dBacklineGreen;
else if (num == 4) dRel = m_dBacklineCyan;
else if (num == 5) dRel = m_dBacklineBlue;
else if (num == 6) dRel = m_dBacklineMagenta;
else if (num == 7) dRel = m_dBacklineWhite;
// if (!DocGetMeterUnitDraw())
// dRel *= 1000;
return dRel;
}
double TRedLine::CalcNo3Step()
{
double S = m_dRedlineArea;
double A1 = m_dBackLineArea; // 退线面积
int a = m_nUpAtuoNum; // 机动车数量
double SI = a * 25.; // 机动车停车面积
int b = m_nUpBikeNum; // 非机动车数量
double SII = b* 1.75; // 非机动车停车面积
double c = m_dGreen; // 绿化率
double SIII = S * c*.01;
double A2 = S - SI - SII - SIII;
double e = m_dBuildDensity; // 建筑密度
double A3 = S * e;
m_dUpBuildArea *= 10000;
m_dDownBuildArea *= 10000;
m_dVolume = m_dUpBuildArea / m_dRedlineArea;
std::vector<double> areas(0);
areas.push_back(A1);
areas.push_back(A2);
areas.push_back(A3);
std::sort(areas.begin(), areas.end()); // 排序求出最小值
return *areas.begin();
}
bool TRedLine::CalcNo4Step()
{
CString str(_T(""));
double a, b, h1, h2; // 未知
double S1(7000.), S2(21000.), h1Max(75.), h1Min(45.), h2Max(155.), h2Min(90.), abMax(60.), abMin(55.),
d1(8.4), // 建筑线与退线之间的距离
d2(4.), // 建筑线与屋顶采光的距离
dw(4.3); // 屋顶采光半宽
// 先进行验证
AcGeLineSeg3d segDirect = GetBLDirectSeg();
AcGeLineSeg3d segCloses = GetBLClosesSeg();
// 当2*a,,h2都为最小时,其和应该小于退线的方向线段
double dd = segDirect.length();
if (segDirect.length() < (h2Min + abMin + abMin))
{
str.Format(_T("退线边的长度%.2f小于 h2的最小值%.2f与 2*a的小最值%.2f的和."), segDirect.length(), h2Min, 2*abMin);
AfxMessageBox(str);
return false;
}
// 当b,h2都为最小时,其和应该小于退线的垂直于方向线段的高度
//if (segCloses.length() < (h1Min + abMin)) return false;
// 先求h2长度,假设 a = 60 , A为退线方向边的长度,令 A = h2 + 2*a,则h2 = A - 2*a
a = abMax;
double A = segDirect.length();
h2 = A - 2 * a;
if (h2 > h2Max)
{
h2 = h2Max;
// 此时 a = abMax, h2 = h2Max, 与 A 之间一定满足关系,不需再次验证
// 通过验证,则 a 已知,S1已知,求h2
}
else if (h2 < h2Min)
{
h2 = h2Min;
// 此时,由于放大了h2的值,所以 2*a+h2 的值有可能大于A,所以需要再次验证
if (A < h2 + 2*a)
{
// 如果a取最小通过验证,则做几个循环,找到精确值(精为1m)。a应该越大越好。所以a从59开始验证
for (a = 60; a <= 55; a-=.001)
if (A >= h2 + 2 * a) break;
}
}
bool brel(false);
double delta = .1;
CalcLightBuildPoly(a, h2, S1, h1);
while (true)
{
if (h1 <= h1Max && h1 >= h1Min)
{
brel = true;
break;
}
if (h1 < h1Min)
{
h2 -= delta;
if (h2 <= h2Min)
{
str.Format(_T("\nh2为最小值%.2f时,h1=%.2f依然不满足 %.2f < h1 < %.2f。\n,是否继续绘制不标准的曲线?"), h2Min, h1, h1Min, h1Max);
//brel = AfxMessageBox(str, MB_YESNO) == IDYES ? true : false;
brel = true;
break;
}
CalcLightBuildPoly(a, h2, S1, h1);
}
else if (h1 > h2Max)
{
h2 += delta;
if (h2 >= h2Max)
{
str.Format(_T("\nh2为最大值%.2f时,h1=%.2f依然不满足 %.2f < h1 < %.2f。\n,是否继续绘制不标准的曲线?"), h2Max, h1, h1Min, h1Max);
//brel = AfxMessageBox(str, MB_YESNO) == IDYES ? true : false;
brel = true;
break;
}
CalcLightBuildPoly(a, h2, S1, h1);
}
}
if (brel)
{
g_idLight = Insert2MSpace(m_LightBuildPoly, _T("轻资产"));
}
CalcBuildPoly(a, h1, h2, S1, S2, b);
while (true)
{
if (b <= abMax && b >= abMin)
{
brel = true;
break;
}
if (b < abMin)
{
a -= delta;
if (a <= abMin)
{
str.Format(_T("\na为最小值%.2f时,b=%.2f依然不满足 %.2f < b < %.2f。\n,是否继续绘制不标准的曲线?"), abMin, b, abMin, abMax);
//brel = AfxMessageBox(str, MB_YESNO) == IDYES ? true : false;
brel = true;
break;
}
CalcBuildPoly(a, h1, h2, S1, S2, b);
}
else if (b > abMax)
{
a += delta;
if (a >= abMax)
{
str.Format(_T("\na为最大值%.2f时,b=%.2f依然不满足 %.2f < b < %.2f。\n,是否继续绘制不标准的曲线?"), abMax, b, abMin, abMax);
//brel = AfxMessageBox(str, MB_YESNO) == IDYES ? true : false;
brel = true;
break;
}
CalcBuildPoly(a, h1, h2, S1, S2, b);
}
}
if (brel)
{
g_idBuild = Insert2MSpace(m_BuildPoly, _T("总图-建筑轮廓线"));
}
if (brel)
CalcCurtainPoly(b, h1);
return brel;
}
AcGeLineSeg3d TRedLine::GetSegByIdx(const int &idx, const TGGePoly3D &poly)
{
if (idx >= 0 && idx < poly.TotalSegments())
{
TGGeCurveSegment seg;
poly.Nth(idx, seg);
return AcGeLineSeg3d(seg.StartPoint().AsAcGePoint3d(), seg.EndPoint().AsAcGePoint3d());
}
return AcGeLineSeg3d(AcGePoint3d::kOrigin, AcGePoint3d::kOrigin);
}
AcGeLineSeg3d TRedLine::GetBLDirectSeg() { return GetSegByIdx(m_idxDirect, m_BacklinePoly); }
AcGeLineSeg3d TRedLine::GetBLClosesSeg() { return GetSegByIdx(m_idxCloses, m_BacklinePoly); }
AcGeLineSeg3d TRedLine::GetBLOtherSeg() { return GetSegByIdx(m_idxOther, m_BacklinePoly); }
/************************************************************************/
// 此多段线各边与退线各边平行。
// 其中一边与退线方向边重合。长度为 a
// 围成面积为S1=7000
// 在这个算法里,由于a值是固定的,所以底边的长度和方向,和与其相邻两边的方向是固定不动的。
// 取底边的一条邻边(e),令e的另一条邻边(e1)(非底边),向底边方向移动。(e与e1的交点沿e向底边移动。)来得到面积为S1的多段线。
/*
轻建筑左边e2 轻建筑右边e1
方向边的另一边 | | 退线最近边
| | | |
| | | |
| ------------------ 轻建筑底边e | (轻建筑度边与退线方向边重合)
| ptE2 ptE1 | ptE2与ptE1距离为h2
|___________________________________________________| 退线方向边
ptOther ptCloses ptE1与ptCloses的距离为a
*/
/************************************************************************/
bool TRedLine::CalcLightBuildPoly(const double &a, const double &h2, const double &S1, double &h1)
{
AcGePoint3d ptE1(AcGePoint3d::kOrigin); // 轻建筑底边与与右边e1的交点
AcGePoint3d ptE2(AcGePoint3d::kOrigin); // 轻建筑底边与与左边e2的交点
AcGeLineSeg3d segBottom; // 轻建筑曲线的底边。
AcGeLineSeg3d segLeft; // 轻建筑左边
AcGeLineSeg3d segRight; // 轻建筑右边
AcGeLineSeg3d segOther; // 退线方向边的另一边(非最近边)
// 首先取出退线的方向边儿, 与最近边。并得取方向边与最近边的交点
AcGeLineSeg3d segBLDirect = GetBLDirectSeg();
AcGeLineSeg3d segBLCloses = GetBLClosesSeg();
AcGeLineSeg3d segBLOther = GetBLOtherSeg();
// 得到轻建筑左右点坐标(此两点都在退线方向边儿上)
m_vtDirect.normalize();
m_vtDirect *= a;
ptE1 = m_ptCloses + m_vtDirect;
m_vtDirect.normalize();
m_vtDirect *= h2;
ptE2 = ptE1 + m_vtDirect;
// 取与退线方向边重合等长的边,沿着vtE1方向移动,移动时保持与退线方向线段平行。
AcGeLineSeg3d seg = segBLDirect;
m_vtCloses.normalize();
double delta = .0001; // 1/10毫米单位拟合
m_LightBuildPoly.SetClosed();
AcGeRay3d ray1(ptE1, m_vtCloses), ray2(ptE2, m_vtOther);
m_segLightDirect.set(ptE1, ptE2);
m_DimH1 = std::make_pair(ptE1, ptE2);
AcGeVector3d _vt(ptE1 - ptE2);
_vt.normalize();
_vt *= a;
m_DimA1 = std::make_pair(ptE1, ptE1+_vt);
m_DimA2 = std::make_pair(ptE2, ptE2-_vt);
AcGePoint3d pt, ptE;
while (true)
{
m_LightBuildPoly.Reset();
m_LightBuildPoly.AppendNode(ptE1);
m_LightBuildPoly.AppendNode(ptE2);
m_vtCloses.normalize();
m_vtCloses *= delta;
delta += .0001;
seg.transformBy(m_vtCloses);
seg.intersectWith(ray2, pt);
m_LightBuildPoly.AppendNode(pt);
m_segLightOther.set(ptE2, pt);
seg.intersectWith(ray1, pt);
m_LightBuildPoly.AppendNode(pt);
m_segLightCloses.set(ptE1, pt);
m_LightBuildPoly.SetClosed();
double dArea = m_LightBuildPoly.Area();
if (dArea > S1 )
{
ptE = segBLDirect.closestPointTo(pt);
h1 = ptE.distanceTo(pt);
m_DimH2 = std::make_pair(ptE, pt);
break;
}
}
{ // 计算轻资产标注插入点
AcGeVector3d vt = -m_vtDirect;
m_ptInsertLightDim1 = m_segLightOther.endPoint();
vt.normalize();
vt *= 15;
m_ptInsertLightDim1 += vt;
vt = -m_vtOther;
vt.normalize();
vt *= 15;
m_ptInsertLightDim1 += vt;
vt.normalize();
vt *= 15;
m_ptInsertLightDim2 = m_ptInsertLightDim1;
m_ptInsertLightDim2 += vt;
}
return true;
}
// 计算出围绕S1(light build)的处围曲线
/************************************************************************/
/*
建筑线另一边 轻建筑左边e2 轻建筑右边e1
方向边的另一边 | | | 退线最近边(建筑线也在此,与退线最近边重合)
| | | | | |
| | | | | |
| | ------------------ 轻建筑底边e | | (轻建筑度边与退线方向边重合)
| | ptE2 ptE1 | | ptE2与ptE1距离为h2
| |_______________________________________________________| |
| ptB2 ptB1|
|______________________________________________________________________| 退线方向边
ptOther ptCloses ptE1与ptCloses的距离为a
*/
/************************************************************************/
bool TRedLine::CalcBuildPoly(const double &a, const double &h1, const double &h2, const double &S1, const double &S2, double &b)
{
double d1(8.4), // 建筑线与退线之间的距离
d2(4.), // 建筑线与屋顶采光的距离
dw(4.3); // 屋顶采光半宽
AcGeLineSeg3d segBLDirect = GetBLDirectSeg();
AcGeLineSeg3d segBLCloses = GetBLClosesSeg();
AcGeLineSeg3d segBLOther = GetBLOtherSeg();
AcGeVector3d vt(AcGeVector3d::kIdentity);
AcGePoint3d pt(AcGePoint3d::kOrigin);
AcGeLineSeg3d seg;
AcGePoint3d ptB1(AcGePoint3d::kOrigin), ptB2(AcGePoint3d::kOrigin),
ptB11(AcGePoint3d::kOrigin), ptB22(AcGePoint3d::kOrigin),
ptB111(AcGePoint3d::kOrigin), ptB222(AcGePoint3d::kOrigin);
// 得取ptB1与ptB2点
ptB1 = m_ptCloses;
m_vtDirect.normalize();
m_vtDirect*= (h2 + 2 * a);
ptB2 = ptB1 + m_vtDirect;
AcGeRay3d ray1(ptB1, m_vtCloses);
AcGeRay3d ray2(ptB2, m_vtOther);
vt = m_vtDirect;
vt.normalize();
vt *=5;
vt.rotateBy(PI*.5, AcGeVector3d::kZAxis);
pt = segBLDirect.midPoint();
pt = pt + vt;
if ((pt & m_BacklinePoly) != PR_INSIDE)
vt.rotateBy(PI, AcGeVector3d::kZAxis);
vt.normalize();
vt *= d1;
seg = segBLDirect;
seg.transformBy(vt);
ray1.intersectWith(seg, ptB1);
ray2.intersectWith(seg, ptB2);
seg.intersectWith(m_segLightOther, ptB22);
seg.intersectWith(m_segLightCloses, ptB11);
ptB111 = m_segLightCloses.endPoint();
ptB222 = m_segLightOther.endPoint();
// 进行拟合,沿m_vtCloses方向移动seg线段
double delta = .0001;
m_vtCloses.normalize();
m_vtCloses *= (m_segLightCloses.length()+delta);
seg = segBLDirect;
seg.transformBy(m_vtCloses);
while (true)
{
m_BuildPoly.Reset();
m_BuildPoly.AppendNode(ptB1);
seg.intersectWith(ray1, pt);
m_BuildPoly.AppendNode(pt);
seg.intersectWith(ray2, pt);
m_BuildPoly.AppendNode(pt);
m_segBuildCloses.set(ptB2, pt);
seg.intersectWith(ray2, pt);
m_BuildPoly.AppendNode(ptB2);
m_BuildPoly.AppendNode(ptB22);
m_BuildPoly.AppendNode(m_segLightOther.endPoint());
m_BuildPoly.AppendNode(m_segLightCloses.endPoint());
m_BuildPoly.AppendNode(ptB11);
m_BuildPoly.SetClosed();
m_segBuildCloses1.set(ptB1, ptB11);
m_segBuildOther1.set(ptB2, ptB22);
m_vtCloses.normalize();
m_vtCloses *= delta;
delta += .0001;
seg.transformBy(m_vtCloses);
if (m_BuildPoly.Area() > S2)
{
pt = seg.closestPointTo(m_segLightCloses.endPoint());
b = pt.distanceTo(m_segLightCloses.endPoint());
m_DimB = std::make_pair(pt, m_segLightCloses.endPoint());
break;
}
}
return true;
}
void TRedLine::CalcCurtainPoly(const double &b, const double &h1)
{
AcGePoint3d pt(AcGePoint3d::kOrigin);
AcGeVector3d vt(AcGeVector3d::kIdentity);
AcGeLineSeg3d seg, seg1, seg2, seg3;
// 建筑线求得幕墙中线
AcGePoint3d ptMidB1 = m_segBuildCloses1.midPoint();
AcGePoint3d ptMidB2 = m_segBuildOther1.midPoint();
AcGePoint3d ptMid1(ptMidB1), ptMid2(ptMidB2); // 计算步行街长度
vt = m_vtDirect;
vt.normalize();
vt *= 5;
vt.rotateBy(PI*.5, AcGeVector3d::kZAxis);
pt = m_segLightDirect.midPoint();
pt += vt;
if ((pt & m_LightBuildPoly) != PR_INSIDE)
vt.rotateBy(PI, AcGeVector3d::kZAxis);
vt.normalize();
vt *= 4;
ptMidB1 += vt;
ptMidB2 += vt;
vt.normalize();
vt *= (h1 + b*.5);
seg = GetBLDirectSeg();
seg.transformBy(vt);
AcGeLineSeg3d segMid = seg;
{ // 计算步行街长度和插入标注的位置
AcGePoint3d pt1, pt2;
AcGeRay3d ray1(ptMid1, m_vtCloses);
ray1.intersectWith(segMid, pt1);
AcGeRay3d ray2(ptMid2, m_vtOther);
ray2.intersectWith(segMid, pt2);
m_dFootLength += ptMid1.distanceTo(pt1);
m_dFootLength += ptMid2.distanceTo(pt2);
m_dFootLength += pt2.distanceTo(pt1);
AcGeLineSeg3d seg(segMid);
AcGeVector3d vt(m_vtOther);
vt.normalize();
vt *= 15;
seg.transformBy(vt);
ray2.intersectWith(seg, m_ptInsertFootDim);
}
double dw = 4.3; //采光半宽
double dta = 11; // 椭圆a轴
double dtb = 16; // 椭圆b轴
double dtd = 4; // 椭圆与采光的间距
TGGePoly3D poly1, poly2;
AcGePoint3d ptMidLightDirect = m_segLightDirect.midPoint();
vt = m_vtDirect;
vt.normalize();
vt.rotateBy(3*PI*.5, AcGeVector3d::kZAxis);
vt *= dw;
AcGeLineSeg3d segUp = seg;
segUp.transformBy(vt);
AcGeLineSeg3d segDown = seg;
segDown.transformBy(-vt);
pt = segUp.closestPointTo(ptMidLightDirect);
double dUp = pt.distanceTo(ptMidLightDirect);
pt = segDown.closestPointTo(ptMidLightDirect);
double dDown = pt.distanceTo(ptMidLightDirect);
if (dDown > dUp)
{
seg = segUp;
segUp = segDown;
segDown = seg;
}
AcGePoint3d pt1, pt2, pt3, pt4, pt5, pt6;
vt = m_vtDirect;
vt.normalize();
vt *= dw;
pt1 = ptMidB1 - vt;
pt6 = ptMidB1 + vt;
pt = m_segLightCloses.closestPointTo(pt1);
double d1 = pt.distanceTo(pt1);
pt = m_segLightCloses.closestPointTo(pt6);
double d6 = pt.distanceTo(pt6);
if (d1 < d6)
{
pt = pt1;
pt1 = pt6;
pt6 = pt;
}
AcGeRay3d ray1(pt1, m_vtCloses);
ray1.intersectWith(segUp, pt2);
vt = -m_vtDirect;
vt.normalize();
vt *= (dtb + dtd);
pt3 = segUp.closestPointTo(m_segLightDirect.midPoint());
pt3 += vt;
pt4 = segDown.closestPointTo(m_segLightDirect.midPoint());
pt4 += vt;
AcGeRay3d ray2(pt6, m_vtCloses);
ray2.intersectWith(segDown, pt5);
poly1.AppendNode(pt1);
poly1.AppendNode(pt2);
poly1.AppendNode(pt3);
poly1.AppendNode(pt4);
poly1.AppendNode(pt5);
poly1.AppendNode(pt6);
poly1.SetClosed();
vt = m_vtDirect;
vt.normalize();
vt *= dw;
pt1 = ptMidB2 + vt;
pt6 = ptMidB2 - vt;
pt = m_segLightOther.closestPointTo(pt1);
d1 = pt.distanceTo(pt1);
pt = m_segLightOther.closestPointTo(pt6);
d6 = pt.distanceTo(pt6);
if (d1 < d6)
{
pt = pt1;
pt1 = pt6;
pt6 = pt;
}
AcGeRay3d ray3(pt1, m_vtOther);
ray3.intersectWith(segUp, pt2);
vt = m_vtDirect;
vt.normalize();
vt *= (dtb + dtd);
pt3 = segUp.closestPointTo(m_segLightDirect.midPoint());
pt3 += vt;
pt4 = segDown.closestPointTo(m_segLightDirect.midPoint());
pt4 += vt;
AcGeRay3d ray4(pt6, m_vtOther);
ray4.intersectWith(segDown, pt5);
poly2.AppendNode(pt1);
poly2.AppendNode(pt2);
poly2.AppendNode(pt3);
poly2.AppendNode(pt4);
poly2.AppendNode(pt5);
poly2.AppendNode(pt6);
poly2.SetClosed();
AcDbObjectId id1 = Insert2MSpace(poly1, _T("总图-采光顶"));
AcDbObjectId id2 = Insert2MSpace(poly2, _T("总图-采光顶"));
pt = segMid.closestPointTo(m_segLightDirect.midPoint());
vt = m_vtDirect;
vt.normalize();
vt *= 16;
AcDbEllipse *pE = new AcDbEllipse(pt, AcGeVector3d::kZAxis, vt, 11./16.);
pE->setLayer(_T("总图-采光顶"));
AcDbObjectId id3 = AddToModelSpace(pE);
AcDbObjectIdArray ar;
ar.append(id1);
CreateHatchForObj(ar);
ar.append(id1);
ar.removeAll();
ar.append(id2);
CreateHatchForObj(ar);
ar.removeAll();
ar.append(id3);
CreateHatchForObj(ar);
}
void TRedLine::CalcDim()
{
TGGeCurveSegment seg;
TGGeLine line;
AcGePoint3d pt, ptMid;
for (size_t i = 0; i < m_RedSegs.size(); ++i)
{
m_BacklinePoly.Nth(i, seg);
line.SetStartPoint(seg.StartPoint());
line.SetEndPoint(seg.EndPoint());
pt = m_RedSegs[i].closestPointTo(line.MidPoint().AsAcGePoint3d());
Dim2Pt(pt, line.MidPoint().AsAcGePoint3d());
}
Dim2Pt(m_DimA1.first, m_DimA1.second);
Dim2Pt(m_DimA2.first, m_DimA2.second);
Dim2Pt(m_DimB.first, m_DimB.second);
Dim2Pt(m_DimH1.first, m_DimH1.second);
Dim2Pt(m_DimH2.first, m_DimH2.second);
}