#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 &lines, LPCTSTR str) { XPushVar osmode(_T("OSMODE"), 0); XPoint point; double dist(.0); std::map 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 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 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); }