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

1369 lines
39 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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);
}