|
- // ************************************************************************** //
- // SelectTarget.cpp : implementation of the CSelectTarget class
- // Copyright(c)2010 Naiky Company. All rights reserved.
- //
- // Abstract:
- // 本文件中实现了CSelectTarget类,图形的选择功能。
- //
- // ******************** Version 1 *******************
- // [维护人员]: 王搂 [维护日期]: 2010-05-20
- // [维护内容]: 建立初版。
- // ************************************************************************** //
-
- #include "stdafx.h"
- #include "SelectTarget.h"
-
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
-
- // 相似图形判断时只精确都小数点后三位。 ---- 黄海燕 2016-01-07
- #define DOUBLE_ROUGHEQU(nX_, nY_) ncmath::IsEqual(nX_, nY_, 1e-3)
-
- using namespace nce;
- using namespace ncmath;
-
- CS_T s_szLAYERN = _DEFCS(_CSV(17152),
- _CHINESE("图层%d")
- _ENGLISH("Layer %d"));
- CS_T s_szTITLE = _DEFCS(_CSV(17160),
- _CHINESE("选择小图形")
- _ENGLISH("Select Tiny"));
- CS_T s_szSELECT_X = _DEFCS(_CSV(17161),
- _CHINESE("X尺寸小于")
- _ENGLISH("X less than"));
- CS_T s_szSELECT_Y = _DEFCS(_CSV(17162),
- _CHINESE("Y尺寸小于")
- _ENGLISH("Y less than"));
- CS_T s_szOK = _DEFCS(_CSV(17163),
- _CHINESE("确定")
- _ENGLISH("OK"));
- CS_T s_szCANCEL = _DEFCS(_CSV(17164),
- _CHINESE("取消")
- _ENGLISH("Cancel"));
-
- ////////////////////////////////////////////////////////////////////////////////
- // 选择小图形的对话框 ---- 杨开锦 2015-11-29
- //
- class CSelectTinyDlg : public CDialog
- {
- DECLARE_DYNAMIC(CSelectTinyDlg)
-
- public:
- CSelectTinyDlg(CWnd* pParent_ = NULL);
- virtual ~CSelectTinyDlg();
-
- GUARD_BEGIN(CSelectTinyDlg);
- double m_nWidth;
- double m_nHeight;
- GUARD_END(CSelectTinyDlg);
-
- protected:
- virtual void DoDataExchange(CDataExchange* pDX_);
- virtual BOOL OnInitDialog();
- };
-
- IMPLEMENT_DYNAMIC(CSelectTinyDlg, CDialog)
-
- CSelectTinyDlg::CSelectTinyDlg(CWnd* pParent_/* = NULL*/)
- : CDialog(IDD_DLG_SELECTTINY, pParent_)
- {
- m_nWidth = 1.0;
- m_nHeight = 1.0;
- LOAD_PARAM(this, CSelectTinyDlg);
- }
-
- CSelectTinyDlg::~CSelectTinyDlg()
- {
- SAVE_PARAM(this, CSelectTinyDlg);
- }
-
- void CSelectTinyDlg::DoDataExchange(CDataExchange* pDX_)
- {
- CDialog::DoDataExchange(pDX_);
-
- DDX_Text(pDX_, IDC_EDT_SELECTTINY_X, m_nWidth);
- DDV_MinMaxDouble(pDX_, m_nWidth, 0.1, 100.0);
- DDX_Text(pDX_, IDC_EDT_SELECTTINY_Y, m_nHeight);
- DDV_MinMaxDouble(pDX_, m_nHeight, 0.1, 100.0);
- }
-
- BOOL CSelectTinyDlg::OnInitDialog()
- {
- if (!__super::OnInitDialog())
- return FALSE;
-
- // 为对话框添加英文界面 ---- 边俊霞 2016-01-25
- SetWindowText(_GETCS(s_szTITLE));
- SetDlgItemText(IDC_STC_SELECTTINY_X, _GETCS(s_szSELECT_X));
- SetDlgItemText(IDC_STC_SELECTTINY_Y, _GETCS(s_szSELECT_Y));
- SetDlgItemText(IDOK, _GETCS(s_szOK));
- SetDlgItemText(IDCANCEL, _GETCS(s_szCANCEL));
-
- return TRUE;
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // Local function declarations
- //
- // 根据一个给定的观察窗,将给定的一组CAD对象划分为以下三个部分,划分的判断办法是
- // 求对象的外接矩形,然后用外接矩形的包含和相交关系来判断。
- // FullInside : 对象完全在观察窗内
- // PartInside : 对象部分在观察窗内
- // NotInside : 对象完全不在观察窗内
- // 观察窗ViewPort应为有效,即其位置点应为有效,宽高应为非负。三个用于OUT的指针均
- // 可以为NULL,为NULL时表示不需要收集这一部分的对象。 ---- 杨开锦 2011-07-16
- static void _DivideObjectsIntoThree(const CadObjectList* plistSource_, const DRECT& rcViewport_,
- CadObjectList* plistFullInside_, CadObjectList* plistPartInside_, CadObjectList* plistNotInside_);
-
- ////////////////////////////////////////////////////////////////////////////////
- // CSelectTarget ---- 杨开锦 2011-07-16
- //
- CSelectTarget* CSelectTarget::ms_pSelectTarget = NULL;
-
- CSelectTarget* GetSelectTarget()
- {
- return CSelectTarget::ms_pSelectTarget;
- }
-
- IMPLEMENT_DYNAMIC(CSelectTarget, CMouseMsgTarget)
- BEGIN_MESSAGE_MAP(CSelectTarget, CMouseMsgTarget)
- ON_COMMAND(IDCMD_SELECTTARGET_SELECT, OnSelect)
- ON_UPDATE_COMMAND_UI(IDCMD_SELECTTARGET_SELECT, OnUpdateSelect)
- ON_COMMAND(IDCMD_SELECTTARGET_SELECTALL, OnSelectAll)
- ON_UPDATE_COMMAND_UI(IDCMD_SELECTTARGET_SELECTALL, OnUpdateSelectAll)
- ON_COMMAND(IDCMD_SELECTTARGET_SELECTUNCLOSE, OnSelectUnclose)
- ON_UPDATE_COMMAND_UI(IDCMD_SELECTTARGET_SELECTUNCLOSE, OnUpdateSelectUnclose)
- ON_COMMAND(IDCMD_SELECTTARGET_SELECTTINY, OnSelectTiny)
- ON_UPDATE_COMMAND_UI(IDCMD_SELECTTARGET_SELECTTINY, OnUpdateSelectTiny)
- ON_COMMAND_RANGE(IDCMD_SELECTTARGET_SELECTBYCOLOR0, IDCMD_SELECTTARGET_SELECTBYCOLOR7, OnSelectByColor)
- ON_UPDATE_COMMAND_UI_RANGE(IDCMD_SELECTTARGET_SELECTBYCOLOR0, IDCMD_SELECTTARGET_SELECTBYCOLOR7, OnUpdateSelectByColor)
- ON_COMMAND_RANGE(IDCMD_SELECTTARGET_SELECTBYTYPE0, IDCMD_SELECTTARGET_SELECTBYTYPE15, OnSelectByType)
- ON_UPDATE_COMMAND_UI_RANGE(IDCMD_SELECTTARGET_SELECTBYTYPE0, IDCMD_SELECTTARGET_SELECTBYTYPE15, OnUpdateSelectByType)
- ON_COMMAND(IDCMD_SELECTTARGET_SELECTREV, OnSelectRev)
- ON_UPDATE_COMMAND_UI(IDCMD_SELECTTARGET_SELECTREV, OnUpdateSelectRev)
- ON_COMMAND(IDCMD_SELECTTARGET_CLEARSELECT, OnClearSelect)
- ON_UPDATE_COMMAND_UI(IDCMD_SELECTTARGET_CLEARSELECT, OnUpdateClearSelect)
- ON_TARGET_MESSAGE(TM_SELECT_SELECTALL, SelectAll)
- ON_TARGET_MESSAGE(TM_SELECT_SELECTBYCOLORE, SelectByColore)
- ON_COMMAND(IDCMD_SELECTTARGET_SELECTSIMILAR, OnSelectSimilar)
- ON_UPDATE_COMMAND_UI(IDCMD_SELECTTARGET_SELECTSIMILAR, OnUpdateSelectSimilar)
- END_MESSAGE_MAP()
-
- CSelectTarget::CSelectTarget(CNceDC* pNceDC_)
- {
- ASSERT(ms_pSelectTarget == NULL);
- ms_pSelectTarget = this;
-
- m_pFileTarget = NULL;
- m_pNceDC = pNceDC_;
- m_nSeleToleranceDP = 6;
- m_ptLButtonDown = DPOINT2(c_nINVALID_DOUBLE, c_nINVALID_DOUBLE);
- m_ptTemp = DPOINT2(c_nINVALID_DOUBLE, c_nINVALID_DOUBLE);
- m_rcSelObjsBoundRect = DRECT(c_nINVALID_DOUBLE, c_nINVALID_DOUBLE, c_nINVALID_DOUBLE, c_nINVALID_DOUBLE);
-
- // 右键菜单 ---- 杨开锦 2010-08-16
- m_pRButtonMenu_NoneSelected = NULL;
- m_pRButtonMenu_SingleSelected = NULL;
- m_pRButtonMenu_MultiSelected = NULL;
-
- m_hCursor = AfxGetApp()->LoadCursor(IDC_CUR_SELECT);
- }
-
- CSelectTarget::~CSelectTarget()
- {
- ASSERT(ms_pSelectTarget == this);
- ms_pSelectTarget = NULL;
- }
-
- void CSelectTarget::Initialize()
- {
- __super::Initialize();
-
- m_pFileTarget = GetFileTarget();
- ASSERT(m_pFileTarget);
-
- // 把选择Target放在鼠标消息遍历链表的最后,即所有的Target都不处理时再判断选择Target是否处理
- // Wanglou 2010-06-13
- MouseMsgTargetList* _pMsgTargetList = GetMouseMsgTargetList();
- _pMsgTargetList->remove(this);
- _pMsgTargetList->push_back(this);
- }
-
- // 更新相关缓存,包括选中对象链表、选中参考线链表、选中对象外接矩形等。 ---- 杨开锦 2011-06-10
- BOOL CSelectTarget::Update(UINT nSenderID_, WPARAM nHint_, LPARAM pObject_)
- {
- GetSelectedCadObjects(true);
- GetSelectedRefLines(true);
- GetSelObjsBoundRect(true);
-
- // 更新特征信息缓存 ---- 杨开锦 2015-11-29
- m_nCloseCount = 0;
- m_nUncloseCount = 0;
- m_nColorMask = 0;
- m_nTypeMask = 0;
- CCadGroup* _pCadGroup = m_pFileTarget->GetCurrentCadGroup();
- ASSERT(_pCadGroup);
- int _nCount = _pCadGroup->GetNumOfChild();
- for (int _i = 0; _i < _nCount; _i++)
- {
- CCadObject* _pCad = _pCadGroup->GetAt(_i);
- ASSERT(_pCad);
- if (_pCad->IsClose())
- m_nCloseCount++;
- else
- m_nUncloseCount++;
-
- m_nColorMask |= (1 << _pCad->GetParamIndex());
-
- if (_pCad->GetType() == caddot) m_nTypeMask |= 0x0001;
- if (_pCad->GetType() == cadline) m_nTypeMask |= 0x0002;
- if (_pCad->GetType() == cadbeeline) m_nTypeMask |= 0x0004;
- if (_pCad->GetType() == cadcircle) m_nTypeMask |= 0x0008;
- if (_pCad->GetType() == cadarc) m_nTypeMask |= 0x0010;
- if (_pCad->GetType() == cadellipse) m_nTypeMask |= 0x0020;
- if (_pCad->GetType() == cadellipsearc) m_nTypeMask |= 0x0040;
- if (_pCad->GetType() == cadrectangle) m_nTypeMask |= 0x0100;
- if (_pCad->GetType() == cadpolygon) m_nTypeMask |= 0x0200;
- if (_pCad->GetType() == cadstar) m_nTypeMask |= 0x0400;
- if (_pCad->GetType() == cadpolyline) m_nTypeMask |= 0x0800;
- if (_pCad->GetType() == cadgroup) m_nTypeMask |= 0x2000;
- if (_pCad->GetType() == cadtext) m_nTypeMask |= 0x4000;
- }
-
- return TRUE;
- }
-
- void CSelectTarget::Activate()
- {
- // Base class first ---- 杨开锦 2010-07-14
- __super::Activate();
-
- // 进入选择模式就是清除所有模式 ---- 杨开锦 2010-05-28
- while (!ms_stackPreMouseMsgTargets.empty())
- ms_stackPreMouseMsgTargets.pop();
- }
-
- void CSelectTarget::OnSelect()
- {
- Activate();
- }
-
- void CSelectTarget::OnUpdateSelect(CCmdUI *pCmdUI_)
- {
- if (IsActive() || GetActiveTarget() == NULL)
- pCmdUI_->SetCheck(TRUE);
- else
- pCmdUI_->SetCheck(FALSE);
- }
-
- void CSelectTarget::OnSelectAll()
- {
- // 进入了其他鼠标操作则禁用选择功能 ---- 杨开锦 2010-07-17
- if (!IsActive() && GetActiveTarget() != NULL)
- return;
-
- SelectAll();
- UpdateAllVisions();
- }
-
- void CSelectTarget::OnUpdateSelectAll(CCmdUI* pCmdUI_)
- {
- // 进入了其他鼠标操作则禁用选择功能 ---- 杨开锦 2010-07-17
- if (!IsActive() && GetActiveTarget() != NULL)
- {
- pCmdUI_->Enable(FALSE);
- return;
- }
-
- pCmdUI_->Enable((m_nCloseCount + m_nUncloseCount) > 0);
- }
-
- void CSelectTarget::OnSelectRev()
- {
- // 进入了其他鼠标操作则禁用选择功能 ---- 杨开锦 2010-07-17
- if (!IsActive() && GetActiveTarget() != NULL)
- return;
-
- SelectRev();
- UpdateAllVisions();
- }
-
- void CSelectTarget::OnUpdateSelectRev(CCmdUI* pCmdUI_)
- {
- // 进入了其他鼠标操作则禁用选择功能 ---- 杨开锦 2010-07-17
- if (!IsActive() && GetActiveTarget() != NULL)
- {
- pCmdUI_->Enable(FALSE);
- return;
- }
-
- pCmdUI_->Enable((m_nCloseCount + m_nUncloseCount) > 0);
- }
-
- void CSelectTarget::OnClearSelect()
- {
- // 进入了其他鼠标操作则禁用选择功能 ---- 杨开锦 2010-07-17
- if (!IsActive() && GetActiveTarget() != NULL)
- return;
-
- ClearSelect();
- UpdateAllVisions();
- }
-
- void CSelectTarget::OnUpdateClearSelect(CCmdUI* pCmdUI_)
- {
- // 进入了其他鼠标操作则禁用选择功能 ---- 杨开锦 2010-07-17
- if (!IsActive() && GetActiveTarget() != NULL)
- {
- pCmdUI_->Enable(FALSE);
- return;
- }
-
- pCmdUI_->Enable(m_listSelectedCadObjects.size() > 0 || GetSelectedRefLines()->size() > 0);
- }
-
- void CSelectTarget::OnSelectUnclose()
- {
- if (!IsActive() && GetActiveTarget() != NULL)
- return;
-
- ASSERT(m_pFileTarget);
- CCadGroup* _pCadGroup = m_pFileTarget->GetCurrentCadGroup();
- for (int _i = 0; _i < _pCadGroup->GetNumOfChild(); _i++)
- {
- CCadObject* _pCad = _pCadGroup->GetAt(_i);
- ASSERT(_pCad);
- _pCad->Select(_pCad->GetType() != cadgroup && !_pCad->IsClose());
- }
-
- GetSelectedCadObjects(true);
- UpdateAllVisions();
- }
-
- void CSelectTarget::OnUpdateSelectUnclose(CCmdUI* pCmdUI_)
- {
- if (!IsActive() && GetActiveTarget() != NULL)
- {
- pCmdUI_->Enable(FALSE);
- return;
- }
-
- pCmdUI_->Enable(m_nUncloseCount > 0);
- }
-
- void CSelectTarget::OnSelectTiny()
- {
- if (!IsActive() && GetActiveTarget() != NULL)
- return;
-
- // 要弹出对话框填尺寸 ---- 杨开锦 2015-11-29
- CSelectTinyDlg _dlg;
- if (_dlg.DoModal() != IDOK)
- return;
-
- double _nWidth = max(0.1, _dlg.m_nWidth);
- double _nHeight = max(0.1, _dlg.m_nHeight);
- ASSERT(m_pFileTarget);
- CCadGroup* _pCadGroup = m_pFileTarget->GetCurrentCadGroup();
- for (int _i = 0; _i < _pCadGroup->GetNumOfChild(); _i++)
- {
- CCadObject* _pCad = _pCadGroup->GetAt(_i);
- ASSERT(_pCad);
- DRECT _rc = _pCad->GetBoundRect();
- _pCad->Select(DOUBLE_LESS(_rc.width, _nWidth) && DOUBLE_LESS(_rc.height, _nHeight));
- }
-
- GetSelectedCadObjects(true);
- UpdateAllVisions();
- }
-
- void CSelectTarget::OnUpdateSelectTiny(CCmdUI* pCmdUI_)
- {
- if (!IsActive() && GetActiveTarget() != NULL)
- {
- pCmdUI_->Enable(FALSE);
- return;
- }
-
- pCmdUI_->Enable((m_nCloseCount + m_nUncloseCount) > 0);
- }
-
- void CSelectTarget:: OnSelectByColor(UINT nID_)
- {
- if (!IsActive() && GetActiveTarget() != NULL)
- return;
-
- // 要选择第几个图层,Base0 ---- 杨开锦 2015-11-29
- int _nParamIndex = nID_ - IDCMD_SELECTTARGET_SELECTBYCOLOR0;
-
- ASSERT(m_pFileTarget);
- CCadGroup* _pCadGroup = m_pFileTarget->GetCurrentCadGroup();
- for (int _i = 0; _i < _pCadGroup->GetNumOfChild(); _i++)
- {
- CCadObject* _pCad = _pCadGroup->GetAt(_i);
- ASSERT(_pCad);
- _pCad->Select(_pCad->GetParamIndex() == _nParamIndex);
- }
-
- GetSelectedCadObjects(true);
- UpdateAllVisions();
- }
-
- void CSelectTarget::OnUpdateSelectByColor(CCmdUI* pCmdUI_)
- {
- // 更新POPUP菜单 ---- 杨开锦 2015-11-29
- if (pCmdUI_->m_pSubMenu != NULL)
- {
- bool _bEnable = (IsActive() || GetActiveTarget() == NULL) && m_nColorMask != 0;
- pCmdUI_->m_pMenu->EnableMenuItem(pCmdUI_->m_nIndex, MF_BYPOSITION | (_bEnable ? MF_ENABLED : MF_GRAYED));
- return;
- }
-
- if (m_nColorMask == 0)
- {
- return;
- }
-
- // 更新子菜单时显示当前有哪些颜色的图形 ---- 杨开锦 2015-11-29
- CMenu* pMenu_ = pCmdUI_->m_pMenu;
- if (pMenu_ == NULL || pCmdUI_->m_nIndex != 0)
- {
- return;
- }
-
- for (int _i = 0; _i < 8; _i++)
- {
- pMenu_->DeleteMenu(IDCMD_SELECTTARGET_SELECTBYCOLOR0 + _i, MF_BYCOMMAND);
- }
-
- for (int _i = 0; _i < 8; _i++)
- {
- if (!(m_nColorMask & (1 << _i)))
- continue;
-
- CString _strName;
- _strName.Format(_GETCS(s_szLAYERN), _i + 1);
- pMenu_->InsertMenu(pCmdUI_->m_nIndex++, MF_STRING | MF_BYPOSITION, IDCMD_SELECTTARGET_SELECTBYCOLOR0 + _i, _strName);
- }
-
- // update end menu count
- pCmdUI_->m_nIndex--; // point to last menu added
- pCmdUI_->m_nIndexMax = pMenu_->GetMenuItemCount();
-
- pCmdUI_->m_bEnableChanged = TRUE; // all the added items are enabled
- }
-
- void CSelectTarget::OnSelectByType(UINT nID_)
- {
- if (!IsActive() && GetActiveTarget() != NULL)
- return;
-
- // 要选择哪种类型的 ---- 杨开锦 2015-11-29
- cad_t _nType = cadobject;
- if (nID_ == IDCMD_SELECTTARGET_SELECTBYTYPE0 + 0) _nType = caddot;
- if (nID_ == IDCMD_SELECTTARGET_SELECTBYTYPE0 + 1) _nType = cadline;
- if (nID_ == IDCMD_SELECTTARGET_SELECTBYTYPE0 + 2) _nType = cadbeeline;
- if (nID_ == IDCMD_SELECTTARGET_SELECTBYTYPE0 + 3) _nType = cadcircle;
- if (nID_ == IDCMD_SELECTTARGET_SELECTBYTYPE0 + 4) _nType = cadarc;
- if (nID_ == IDCMD_SELECTTARGET_SELECTBYTYPE0 + 5) _nType = cadellipse;
- if (nID_ == IDCMD_SELECTTARGET_SELECTBYTYPE0 + 6) _nType = cadellipsearc;
- if (nID_ == IDCMD_SELECTTARGET_SELECTBYTYPE0 + 8) _nType = cadrectangle;
- if (nID_ == IDCMD_SELECTTARGET_SELECTBYTYPE0 + 9) _nType = cadpolygon;
- if (nID_ == IDCMD_SELECTTARGET_SELECTBYTYPE0 + 10) _nType = cadstar;
- if (nID_ == IDCMD_SELECTTARGET_SELECTBYTYPE0 + 11) _nType = cadpolyline;
- if (nID_ == IDCMD_SELECTTARGET_SELECTBYTYPE0 + 13) _nType = cadgroup;
- if (nID_ == IDCMD_SELECTTARGET_SELECTBYTYPE0 + 14) _nType = cadtext;
-
- ASSERT(m_pFileTarget);
- CCadGroup* _pCadGroup = m_pFileTarget->GetCurrentCadGroup();
- for (int _i = 0; _i < _pCadGroup->GetNumOfChild(); _i++)
- {
- CCadObject* _pCad = _pCadGroup->GetAt(_i);
- ASSERT(_pCad);
- _pCad->Select(_pCad->GetType() == _nType);
- }
-
- GetSelectedCadObjects(true);
- UpdateAllVisions();
- }
-
- void CSelectTarget:: OnUpdateSelectByType(CCmdUI* pCmdUI_)
- {
- // 更新POPUP菜单 ---- 杨开锦 2015-11-29
- if (pCmdUI_->m_pSubMenu != NULL)
- {
- bool _bEnable = (IsActive() || GetActiveTarget() == NULL) && m_nTypeMask != 0;
- pCmdUI_->m_pMenu->EnableMenuItem(pCmdUI_->m_nIndex, MF_BYPOSITION | (_bEnable ? MF_ENABLED : MF_GRAYED));
- return;
- }
-
- if (m_nTypeMask == 0)
- {
- return;
- }
-
- // 更新子菜单时显示当前有哪些颜色的图形 ---- 杨开锦 2015-11-29
- CMenu* pMenu_ = pCmdUI_->m_pMenu;
- if (pMenu_ == NULL || pCmdUI_->m_nIndex != 0)
- {
- return;
- }
-
- for (int _i = 0; _i < 15; _i++)
- {
- pMenu_->DeleteMenu(IDCMD_SELECTTARGET_SELECTBYTYPE0 + _i, MF_BYCOMMAND);
- }
-
- static const CString c_sstrNames[] =
- {
- CCadDot().GetName(),
- CCadLine().GetName(),
- CCadBeeline().GetName(),
- CCadCircle().GetName(),
- CCadArc().GetName(),
- CCadEllipse().GetName(),
- CCadEllipseArc().GetName(),
- _T("CadMmultiSegments"),
- CCadRectangle().GetName(),
- CCadPolygon().GetName(),
- CCadStar().GetName(),
- CCadPolyline().GetName(),
- _T("CadPath"),
- CCadGroup().GetName(),
- CCadText().GetName(),
- _T("CadBmp"),
- };
- for (int _i = 0; _i < 15; _i++)
- {
- if (!(m_nTypeMask & (1 << _i)))
- continue;
-
- CString _strName = c_sstrNames[_i];
- pMenu_->InsertMenu(pCmdUI_->m_nIndex++, MF_STRING | MF_BYPOSITION, IDCMD_SELECTTARGET_SELECTBYTYPE0 + _i, _strName);
- }
-
- // update end menu count
- pCmdUI_->m_nIndex--; // point to last menu added
- pCmdUI_->m_nIndexMax = pMenu_->GetMenuItemCount();
-
- pCmdUI_->m_bEnableChanged = TRUE; // all the added items are enabled
- }
-
- // 鼠标左键按下的响应函数 Wanglou 2010-06-13
- BOOL CSelectTarget::OnLButtonDown(UINT nFlags_, DPOINT2 point_)
- {
- if (!IsActive() && GetActiveTarget() != NULL)
- return FALSE;
-
- if (IsInvalidDouble(m_ptLButtonDown.x) || IsInvalidDouble(m_ptLButtonDown.y))
- m_ptLButtonDown = point_;
- return TRUE;
- }
-
- // 坐标左键弹起的响应函数 Wanglou 2010-06-13
- BOOL CSelectTarget::OnLButtonUp(UINT nFlags_, DPOINT2 point_)
- {
- if (!IsActive() && GetActiveTarget() != NULL)
- return FALSE;
-
- if (IsInvalidDouble(m_ptLButtonDown.x) || IsInvalidDouble(m_ptLButtonDown.y))
- return FALSE;
-
- CadObjectList _listSelectedCads = *GetSelectedCadObjects();
- CadObjectList _listSelectedRefs = *GetSelectedRefLines();
-
- // 放宽鼠标点击的判断条件,点下和弹起的地方可以不是同一个点,但必须足够近,
- // 点下和弹起处的距离不超过点选容差的1/2则认为是点击,即认为是点选,否则则
- // 为框选。 ---- 杨开锦 2011-07-16
- double _nTolerance = GetSelectToleranceLP();
- if (abs(m_ptLButtonDown.x - point_.x) <= _nTolerance / 2.
- && abs(m_ptLButtonDown.y - point_.y) <= _nTolerance / 2.)
- {
- SelectByPoint(nFlags_, point_, _nTolerance);
- }
- else
- {
- SelectByRect(nFlags_, m_ptLButtonDown, point_);
- }
-
- // 发送消息告诉所有Target选择的对象发生了改变 Wanglou 2010-06-13
- //SendTargetMessage(ID_TARGET_BROADCAST, TN_SELECT_CHANGE, (WPARAM)GetSelectedCadObjects());//&m_listSelectedCadObjects);
- Reset();
-
- bool _bChanged = _listSelectedCads != *GetSelectedCadObjects() || _listSelectedRefs != *GetSelectedRefLines();
- if (_bChanged)
- {
- // 因为变化而更新 ---- 王斌 2013.06.17
- UpdateAllVisions();
- }
- else
- {
- // 没有变化也要更新自己(考虑选择框) ---- 王斌 2013.06.17
- UpdateVisions();
- }
- return TRUE;
- }
-
- BOOL CSelectTarget::OnRButtonUp(UINT nFlags_, DPOINT2 point_)
- {
- if (!IsActive() && GetActiveTarget() != NULL)
- return FALSE;
-
- if (IsValidDouble(m_ptLButtonDown.x) || IsValidDouble(m_ptLButtonDown.y))
- {
- Reset();
- UpdateVisions();
- }
- else
- {
- // 求鼠标位置(Screen坐标) ---- 杨开锦 2010-08-16
- ASSERT(m_pNceDC);
- CPoint _ptPos = m_pNceDC->LPtoDP_Point(point_);
- CWnd* _pWnd = m_pNceDC->GetWindow();
- ASSERT(_pWnd);
- _pWnd->ClientToScreen(&_ptPos);
-
- // 弹出右键菜单 ---- 杨开锦 2010-08-16
- // 添加选中参考线时的右键菜单-------liangyan 2013-10-23
- if (m_listSelectedCadObjects.size() == 0 && m_pRButtonMenu_NoneSelected && m_listSelectedRefLines.size() == 0)
- m_pRButtonMenu_NoneSelected->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON , _ptPos.x, _ptPos.y, AfxGetMainWnd());
- else if (m_listSelectedCadObjects.size() == 1 && m_pRButtonMenu_SingleSelected)
- m_pRButtonMenu_SingleSelected->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON , _ptPos.x, _ptPos.y, AfxGetMainWnd());
- else if (m_pRButtonMenu_MultiSelected || m_listSelectedRefLines.size() != 0)
- m_pRButtonMenu_MultiSelected->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON , _ptPos.x, _ptPos.y, AfxGetMainWnd());
- }
-
- return TRUE;
- }
-
- BOOL CSelectTarget::OnMouseMove(UINT nFlags_, DPOINT2 point_)
- {
- if (!IsActive() && GetActiveTarget() != NULL)
- return FALSE;
-
- if (IsInvalidDouble(m_ptLButtonDown.x) || IsInvalidDouble(m_ptLButtonDown.y))
- return FALSE;
-
- m_ptTemp = point_;
- UpdateVisions();
- return TRUE;
- }
-
- BOOL CSelectTarget::OnKeyDown(UINT nChar_, UINT nRepCnt_, UINT nFlags_)
- {
- if (nChar_ == VK_ESCAPE && (IsActive() || GetActiveTarget() == NULL))
- {
- // Esc清除选择 ---- 孙彦春 2012-5-27
- ClearSelect();
- UpdateAllVisions();
- return TRUE;
- }
-
- return FALSE;
- }
-
- // 点选功能实现: 首先考虑选择参考线,如果不是选择参考线则根据ctrl、shift键的状态
- // 区分为普通、加选、减选、反选。
- // 点选只考虑一个图形,点到则是1个,点不到则是0个。 ---- 杨开锦 2011-07-16
- // 参考线也根据ctrl、shift键的状态 区分为普通、加选、减选、反选-----liangyan 2013-10-19
- BOOL CSelectTarget::SelectByPoint(UINT nFlags_, const DPOINT2& point_, double nTolerance_)
- {
- bool _bCtrlKeyDown = (nFlags_ & MK_CONTROL) != 0;
- bool _bShiftKeyDown = (nFlags_ & MK_SHIFT) != 0;
- BOOL _nRet = FALSE;
-
- // 区分点选模式 ---- 杨开锦 2011-07-16
- if (!_bCtrlKeyDown && !_bShiftKeyDown)
- {
- if (SelectRefLine(point_, nTolerance_))
- _nRet = TRUE;
- else
- _nRet = _SelectByPoint_Normal(point_, nTolerance_);
- }
- else if (_bCtrlKeyDown && !_bShiftKeyDown)
- {
- _nRet = _SelectByPoint_Increase(point_, nTolerance_);
- }
- else if (!_bCtrlKeyDown && _bShiftKeyDown)
- {
- _nRet = _SelectByPoint_Decrease(point_, nTolerance_);
- }
- else
- {
- ASSERT(_bCtrlKeyDown && _bShiftKeyDown);
- _nRet = _SelectByPoint_Reverse(point_, nTolerance_);
- }
-
- // 更新选中对象链表 ---- 杨开锦 2011-07-16
- GetSelectedCadObjects(true);
- GetSelectedRefLines(true);
- return _nRet;
- }
-
- // 点选--普通模式: 若点到,则选中点到的图形,其他均去选中;若点不到,则所有均去
- // 选中。
- // 首先用点选发生点和点选容差构造一个观察窗矩形,然后根据各图形与这个观察窗的
- // 包含与相交内外关系将所有图形进行分类,考虑相交的图形组的全部、以及包含的图形
- // 组的若干个。 ---- 杨开锦 2011-07-16
- BOOL CSelectTarget::_SelectByPoint_Normal(const DPOINT2& point_, double nTolerance_)
- {
- ASSERT(nTolerance_ >= 0.);
- ASSERT(m_pFileTarget);
-
- // 构造观察窗矩形并分类 ---- 杨开锦 2011-07-16
- DRECT _rcViewport(point_.x - nTolerance_, point_.y - nTolerance_,
- 2. * nTolerance_, 2. * nTolerance_);
- const CadObjectList* _plistCurrentGroup = m_pFileTarget->GetCurrentCadGroup()->GetObjectsList();
- ASSERT(_plistCurrentGroup);
- CadObjectList _listFullInside;
- CadObjectList _listPartInside;
- _DivideObjectsIntoThree(_plistCurrentGroup, _rcViewport, &_listFullInside, &_listPartInside, NULL);
-
- // 收集考虑的图形集 ---- 杨开锦 2011-07-16
- CadObjectList _listTarget;
- const int _c_nMaxCount = 10; // 最多考虑FullInside部分中的N个
- int _nCurCount = 0;
- for (CadObjectList::iterator _it = _listFullInside.begin(); _it != _listFullInside.end(); _it++)
- {
- CCadObject* _pCad = *_it;
- ASSERT(_pCad);
- _listTarget.push_back(_pCad);
- _nCurCount++;
-
- if (_nCurCount >= _c_nMaxCount)
- {
- break;
- }
- }
- for (CadObjectList::iterator _it = _listPartInside.begin(); _it != _listPartInside.end(); _it++)
- {
- CCadObject* _pCad = *_it;
- ASSERT(_pCad);
- _listTarget.push_back(_pCad);
- }
-
- // 命中测试 ---- 杨开锦 2011-07-16
- CCadObject* _pCadSelected = nce::Hit(&_listTarget, point_, nTolerance_, NULL);
-
- // Carry out 计算结果 ---- 杨开锦 2011-07-16
- for (CadObjectList::const_iterator _it = _plistCurrentGroup->begin(); _it != _plistCurrentGroup->end(); _it++)
- {
- CCadObject* _pCad = *_it;
- ASSERT(_pCad);
- _pCad->Select(false);
- }
-
- if (_pCadSelected)
- {
- _pCadSelected->Select(true);
- }
-
- return (_pCadSelected != NULL);
- }
-
- // 点选--加选模式: 若点到,则选中点到的图形;若点不到,则无运作。
- // 因为是加选,仅须考虑当前未选中的图形,已选中的图形不考虑;同前理,用点选发
- // 生点和点选容差构造一个观察窗矩形,然后根据各图形与这个观察窗的包含与相交内外
- // 关系将未选中图形进行分类,考虑相交的图形组的全部、以及包含的图形组的若干个。
- // ---- 杨开锦 2011-07-16
- BOOL CSelectTarget::_SelectByPoint_Increase(const DPOINT2& point_, double nTolerance_)
- {
- ASSERT(nTolerance_ >= 0.);
- ASSERT(m_pFileTarget);
-
- // 构造观察窗矩形并分类 ---- 杨开锦 2011-07-16
- DRECT _rcViewport(point_.x - nTolerance_, point_.y - nTolerance_,
- 2. * nTolerance_, 2. * nTolerance_);
- const CadObjectList* _plistCurrentGroup = m_pFileTarget->GetCurrentCadGroup()->GetObjectsList();
- CCadGroup* _pRefLines = m_pFileTarget->GetCurrentRefLines();
- ASSERT(_plistCurrentGroup || _pRefLines);;
- CadObjectList _listFullInside;
- CadObjectList _listPartInside;
- _DivideObjectsIntoThree(_plistCurrentGroup, _rcViewport, &_listFullInside, &_listPartInside, NULL);
-
- // 收集考虑的图形集 ---- 杨开锦 2011-07-16
- CadObjectList _listTarget;
- const int _c_nMaxCount = 10; // 最多考虑FullInside部分中的N个
- int _nCurCount = 0;
- for (CadObjectList::iterator _it = _listFullInside.begin(); _it != _listFullInside.end(); _it++)
- {
- CCadObject* _pCad = *_it;
- ASSERT(_pCad);
- if (_pCad->IsSelected())
- {
- continue;
- }
-
- _listTarget.push_back(_pCad);
- _nCurCount++;
-
- if (_nCurCount >= _c_nMaxCount)
- {
- break;
- }
- }
- for (CadObjectList::iterator _it = _listPartInside.begin(); _it != _listPartInside.end(); _it++)
- {
- CCadObject* _pCad = *_it;
- ASSERT(_pCad);
- if (!_pCad->IsSelected())
- {
- _listTarget.push_back(_pCad);
- }
- }
- // 命中测试 ---- 杨开锦 2011-07-16
- CCadObject* _pCadSelected = nce::Hit(&_listTarget, point_, nTolerance_, NULL);
- CCadObject* _pRefLinesSelected = Hit(_pRefLines, point_, nTolerance_);
- // 加选时,Cad对象和参考线不能同时选中,如果命中Cad对象,则应先清除所有参考线的选中状态,
- // 如果参考线命中,则应清除所有Cad对象的选中状态-----liangyan 2013-10-19
- int _nCount = _pRefLines->GetNumOfChild();
- if (_pCadSelected)
- {
- for (int _i = 0; _i < _nCount; _i++)
- _pRefLines->GetAt(_i)->Select(false);
- _pCadSelected->Select(true);
- }
- if(_pRefLinesSelected)
- {
- for (CadObjectList::const_iterator _iter = _plistCurrentGroup->begin(); _iter != _plistCurrentGroup->end(); _iter++)
- {
- if ((*_iter)->IsSelected())
- (*_iter)->Select(false);
- }
- _pRefLinesSelected->Select(true);
- }
- return (_pCadSelected != NULL|| _pRefLinesSelected != NULL);
- }
-
- // 点选--减选模式: 若点到,则去选中点到的图形;若点不到,则无运作。
- // 因为是减选,仅须考虑当前已选中的图形,未选中的图形不考虑;同前理,用点选发
- // 生点和点选容差构造一个观察窗矩形,然后根据各图形与这个观察窗的包含与相交内外
- // 关系将已选中图形进行分类,考虑相交的图形组的全部、以及包含的图形组的若干个。
- // ---- 杨开锦 2011-07-16
- BOOL CSelectTarget::_SelectByPoint_Decrease(const DPOINT2& point_, double nTolerance_)
- {
- ASSERT(nTolerance_ >= 0.);
- ASSERT(m_pFileTarget);
-
- // 构造观察窗矩形并分类 ---- 杨开锦 2011-07-16
- DRECT _rcViewport(point_.x - nTolerance_, point_.y - nTolerance_,
- 2. * nTolerance_, 2. * nTolerance_);
- const CadObjectList* _plistSelectedCadObjects = GetSelectedCadObjects();
- CCadGroup* _pRefLines = m_pFileTarget->GetCurrentRefLines();
- ASSERT(_plistSelectedCadObjects || _pRefLines);
- CadObjectList _listFullInside;
- CadObjectList _listPartInside;
- _DivideObjectsIntoThree(_plistSelectedCadObjects, _rcViewport, &_listFullInside, &_listPartInside, NULL);
-
- // 收集考虑的图形集 ---- 杨开锦 2011-07-16
- CadObjectList _listTarget;
- const int _c_nMaxCount = 10; // 最多考虑FullInside部分中的N个
- int _nCurCount = 0;
- for (CadObjectList::iterator _it = _listFullInside.begin(); _it != _listFullInside.end(); _it++)
- {
- CCadObject* _pCad = *_it;
- ASSERT(_pCad);
- _listTarget.push_back(_pCad);
- _nCurCount++;
-
- if (_nCurCount >= _c_nMaxCount)
- {
- break;
- }
- }
- for (CadObjectList::iterator _it = _listPartInside.begin(); _it != _listPartInside.end(); _it++)
- {
- CCadObject* _pCad = *_it;
- ASSERT(_pCad);
- _listTarget.push_back(_pCad);
- }
-
- // 命中测试 ---- 杨开锦 2011-07-16
- CCadObject* _pCadSelected = nce::Hit(&_listTarget, point_, nTolerance_, NULL);
- // Carry out 计算结果 ---- 杨开锦 2011-07-16
- if (_pCadSelected)
- {
- _pCadSelected->Select(false);
- }
- // shift键,参考线的减选功能 ---liangyan 2013-10-19
- CCadObject* _pRefLinesSelected = Hit(_pRefLines, point_, nTolerance_);
- if (_pRefLinesSelected)
- {
- _pRefLinesSelected->Select(false);
- }
- return (_pCadSelected != NULL || _pRefLinesSelected != NULL);
- }
-
- // 点选--反选模式: 若点到,则反转选中状态;若点不到,则无运作。
- // 同前理,用点选发生点和点选容差构造一个观察窗矩形,然后根据各图形与这个观察
- // 窗的包含与相交内外关系将所有图形进行分类,考虑相交的图形组的全部、以及包含的
- // 图形组的若干个。
- // ---- 杨开锦 2011-07-16
- BOOL CSelectTarget::_SelectByPoint_Reverse(const DPOINT2& point_, double nTolerance_)
- {
- ASSERT(nTolerance_ >= 0.);
- ASSERT(m_pFileTarget);
-
- // 构造观察窗矩形并分类 ---- 杨开锦 2011-07-16
- DRECT _rcViewport(point_.x - nTolerance_, point_.y - nTolerance_,
- 2. * nTolerance_, 2. * nTolerance_);
- const CadObjectList* _plistCurrentGroup = m_pFileTarget->GetCurrentCadGroup()->GetObjectsList();
- CCadGroup* _pRefLines = m_pFileTarget->GetCurrentRefLines();
- ASSERT(_plistCurrentGroup || _pRefLines);
- CadObjectList _listFullInside;
- CadObjectList _listPartInside;
- _DivideObjectsIntoThree(_plistCurrentGroup, _rcViewport, &_listFullInside, &_listPartInside, NULL);
-
- // 收集考虑的图形集 ---- 杨开锦 2011-07-16
- CadObjectList _listTarget;
- const int _c_nMaxCount = 10; // 最多考虑FullInside部分中的N个
- int _nCurCount = 0;
- for (CadObjectList::iterator _it = _listFullInside.begin(); _it != _listFullInside.end(); _it++)
- {
- CCadObject* _pCad = *_it;
- ASSERT(_pCad);
- _listTarget.push_back(_pCad);
- _nCurCount++;
-
- if (_nCurCount >= _c_nMaxCount)
- {
- break;
- }
- }
- for (CadObjectList::iterator _it = _listPartInside.begin(); _it != _listPartInside.end(); _it++)
- {
- CCadObject* _pCad = *_it;
- ASSERT(_pCad);
- _listTarget.push_back(_pCad);
- }
-
- // 命中测试 ---- 杨开锦 2011-07-16
- // ctrl + shift反选时,Cad对象和参考线不能同时选中,如果命中Cad对象,则应先清除所有参考线的选中状态,
- // 如果参考线命中,则应清除所有Cad对象的选中状态-----liangyan 2013-10-19
- CCadObject* _pCadSelected = nce::Hit(&_listTarget, point_, nTolerance_, NULL);
- CCadObject* _pRefLinesSelected = Hit(_pRefLines, point_, nTolerance_);
- int _nCount = _pRefLines->GetNumOfChild();
- if (_pCadSelected)
- {
- for (int _i = 0; _i < _nCount; _i++)
- _pRefLines->GetAt(_i)->Select(false);
- _pCadSelected->Select(!_pCadSelected->IsSelected());
- }
- if(_pRefLinesSelected)
- {
- for (CadObjectList::const_iterator _iter = _plistCurrentGroup->begin(); _iter != _plistCurrentGroup->end(); _iter++)
- {
- if ((*_iter)->IsSelected())
- (*_iter)->Select(false);
- }
- _pRefLinesSelected->Select(!_pRefLinesSelected->IsSelected());
- }
- return (_pCadSelected != NULL || _pRefLinesSelected != NULL);
- }
-
- // 框选功能的实现函数,ptFirst_,ptSecond_,为框选矩形一条对角线的两端点 Wanglou 2010-06-13
- UINT CSelectTarget::SelectByRect(UINT nFlags_, const DPOINT2& ptFirst_, const DPOINT2& ptSecond_)
- {
- // 框选不会选中参考线,并且会把参考线的选择状态清除掉 Wanglou 2010-08-21
- ASSERT(m_pFileTarget);
- CCadGroup* _pRefLines = m_pFileTarget->GetCurrentRefLines();
- ASSERT(_pRefLines);
- for (int _i = 0; _i < _pRefLines->GetNumOfChild(); _i++)
- {
- CCadObject* _pCad = _pRefLines->GetAt(_i);
- ASSERT(_pCad);
- _pCad->Select(false);
- }
-
- bool _bCtrlKeyDown = (nFlags_ & MK_CONTROL) != 0;
- bool _bShiftKeyDown = (nFlags_ & MK_SHIFT) != 0;
-
- // 区分框选模式 ---- 杨开锦 2011-07-16
- UINT _nRet = 0;
- if (!_bCtrlKeyDown && !_bShiftKeyDown)
- {
- _nRet = _SelectByRect_Normal(ptFirst_, ptSecond_);
- }
- else if (_bCtrlKeyDown && !_bShiftKeyDown)
- {
- _nRet = _SelectByRect_Increase(ptFirst_, ptSecond_);
- }
- else if (!_bCtrlKeyDown && _bShiftKeyDown)
- {
- _nRet = _SelectByRect_Decrease(ptFirst_, ptSecond_);
- }
- else
- {
- ASSERT(_bCtrlKeyDown && _bShiftKeyDown);
- _nRet = _SelectByRect_Reverse(ptFirst_, ptSecond_);
- }
-
- // 更新选中对象链表 ---- 杨开锦 2011-07-16
- GetSelectedCadObjects(true);
- GetSelectedRefLines(true);
-
- return _nRet;
- }
-
- // 框选--普通模式: 图形在选择框内则被选中,否则去选中。 ---- 杨开锦 2011-07-16
- UINT CSelectTarget::_SelectByRect_Normal(const DPOINT2& ptFirst_, const DPOINT2& ptSecond_)
- {
- // 框选 ---- 杨开锦 2011-07-16
- ASSERT(m_pFileTarget);
- CCadGroup* _pCadGroup = m_pFileTarget->GetCurrentCadGroup();
- ASSERT(_pCadGroup);
- UINT _nRet = 0;
- for (int _i = 0; _i < _pCadGroup->GetNumOfChild(); _i++)
- {
- CCadObject* _pCadObject = _pCadGroup->GetAt(_i);
- ASSERT(_pCadObject);
- if (_SelectCadObjectByRect(_pCadObject, ptFirst_, ptSecond_))
- {
- _pCadObject->Select(true);
- _nRet++;
- }
- else
- {
- _pCadObject->Select(false);
- }
- }
-
- return _nRet;
- }
-
- // 框选--加选模式: 图形在选择框内则被选中,否则无动作。 ---- 杨开锦 2011-07-16
- UINT CSelectTarget::_SelectByRect_Increase(const DPOINT2& ptFirst_, const DPOINT2& ptSecond_)
- {
- // 加选 ---- 杨开锦 2011-07-16
- ASSERT(m_pFileTarget);
- CCadGroup* _pCadGroup = m_pFileTarget->GetCurrentCadGroup();
- ASSERT(_pCadGroup);
- UINT _nRet = 0;
- for (int _i = 0; _i < _pCadGroup->GetNumOfChild(); _i++)
- {
- CCadObject* _pCadObject = _pCadGroup->GetAt(_i);
- ASSERT(_pCadObject);
- if (_SelectCadObjectByRect(_pCadObject, ptFirst_, ptSecond_))
- {
- _pCadObject->Select(true);
- _nRet++;
- }
- }
-
- return _nRet;
- }
-
- // 框选--减选模式: 图形在选择框内则去选中,否则无动作。 ---- 杨开锦 2011-07-16
- UINT CSelectTarget::_SelectByRect_Decrease(const DPOINT2& ptFirst_, const DPOINT2& ptSecond_)
- {
- // 减选 ---- 杨开锦 2011-07-16
- ASSERT(m_pFileTarget);
- CCadGroup* _pCadGroup = m_pFileTarget->GetCurrentCadGroup();
- ASSERT(_pCadGroup);
- UINT _nRet = 0;
- for (int _i = 0; _i < _pCadGroup->GetNumOfChild(); _i++)
- {
- CCadObject* _pCadObject = _pCadGroup->GetAt(_i);
- ASSERT(_pCadObject);
- if (_SelectCadObjectByRect(_pCadObject, ptFirst_, ptSecond_))
- {
- _pCadObject->Select(false);
- _nRet++;
- }
- }
-
- return _nRet;
- }
-
- // 框选--反选模式: 图形在选择框内则反转选中状态,否则无动作。 ---- 杨开锦 2011-07-16
- UINT CSelectTarget::_SelectByRect_Reverse(const DPOINT2& ptFirst_, const DPOINT2& ptSecond_)
- {
- // 反选 ---- 杨开锦 2011-07-16
- ASSERT(m_pFileTarget);
- CCadGroup* _pCadGroup = m_pFileTarget->GetCurrentCadGroup();
- ASSERT(_pCadGroup);
- UINT _nRet = 0;
- for (int _i = 0; _i < _pCadGroup->GetNumOfChild(); _i++)
- {
- CCadObject* _pCadObject = _pCadGroup->GetAt(_i);
- ASSERT(_pCadObject);
- if (_SelectCadObjectByRect(_pCadObject, ptFirst_, ptSecond_))
- {
- bool _bSelected = _pCadObject->IsSelected();
- _pCadObject->Select(!_bSelected);
- _nRet++;
- }
- }
-
- return _nRet;
- }
-
- UINT CSelectTarget::_SelectCadObjectByColore(int nColoreIndex_)
- {
- ASSERT(m_pFileTarget);
- ASSERT(nColoreIndex_ >= 0);
- CCadGroup* _pCadGroup = m_pFileTarget->GetCurrentCadGroup();
-
- UINT _nRet = 0;
- for (int _i = 0; _i < _pCadGroup->GetNumOfChild(); _i++)
- {
- CCadObject* _pCadObject = _pCadGroup->GetAt(_i);
- ASSERT(_pCadObject);
- if(_pCadObject->GetParamIndex() == nColoreIndex_)
- {
- _pCadObject->Select();
- _nRet++;
- }
- else
- {
- _pCadObject->Select(false);
- }
- }
-
- return _nRet;
- }
-
- LRESULT CSelectTarget::SelectByColore(WPARAM wParam_, LPARAM lParam_)
- {
- int _nIndex = (int)wParam_;
- ASSERT(_nIndex >= 0);
-
- return _SelectCadObjectByColore(_nIndex);
- }
-
- void CSelectTarget::OnSelectSimilar()
- {
- // 选中相似图形,先指定一个参照图形,不选或者多选或者选中组都不管。 --- 黄海燕 2015-12-22
- const CadObjectList* _plistRefObjs = GetSelectedCadObjects();
- if (_plistRefObjs->size() != 1
- || (*_plistRefObjs->begin())->GetType() == cadgroup
- || (*_plistRefObjs->begin())->GetType() == cadtext)
- {
- return;
- }
-
- CCadObject* _pRefObj = *(_plistRefObjs->begin());
- switch(_pRefObj->GetType())
- {
- case caddot:
- {
- _SelectSimilarDot((CCadDot*)_pRefObj);
- break;
- }
- case cadline:
- {
- _SelectSimilarLine((CCadLine*)_pRefObj);
- break;
- }
-
- case cadcircle:
- {
- _SelectSimilarCircle((CCadCircle*)_pRefObj);
- break;
- }
-
- case cadarc:
- {
- _SelectSimilarArc((CCadArc*)_pRefObj);
- break;
- }
-
- case cadellipse:
- {
- _SelectSimilarEllipse((CCadEllipse*)_pRefObj);
- break;
- }
-
- case cadellipsearc:
- {
- _SelectSimilarEllipseArc((CCadEllipseArc*)_pRefObj);
- break;
- }
-
- case cadrectangle:
- {
- _SelectSimilarRectangle((CCadRectangle*)_pRefObj);
- break;
- }
-
- case cadpolygon:
- {
- _SelectSimilarPolygon((CCadPolygon*)_pRefObj);
- break;
- }
-
- case cadstar:
- {
- _SelectSimilarStar((CCadStar*)_pRefObj);
- break;
- }
-
- case cadpolyline:
- {
- _SelectSimilarPolyline((CCadPolyline*)_pRefObj);
- break;
- }
-
- default:
- {
- // do noting
- }
- }
-
- UpdateAllVisions();
- }
-
- void CSelectTarget::OnUpdateSelectSimilar(CCmdUI* pCmdUI_)
- {
- const CadObjectList* _pSelectObjs = GetSelectedCadObjects();
- pCmdUI_->Enable(_pSelectObjs && _pSelectObjs->size() > 0);
- }
-
- // 所有的点都是相似的。 ---- 黄海燕 2015-12-22
- void CSelectTarget::_SelectSimilarDot(const nce::CCadDot* pRefDot_)
- {
- if (!pRefDot_)
- {
- ASSERT(FALSE);
- return;
- }
-
- ASSERT(m_pFileTarget);
- CCadGroup* _pCadGroup = m_pFileTarget->GetCurrentCadGroup();
- UINT _nRet = 0;
- for (int _i = 0; _i < _pCadGroup->GetNumOfChild(); _i++)
- {
- CCadObject* _pCadObject = _pCadGroup->GetAt(_i);
- ASSERT(_pCadObject);
- // 自己肯定长得像自己,不过这里的前提是每个对象的ID是唯一的。 ---- 黄海燕 2016-01-07
- if (_pCadObject->GetID() == pRefDot_->GetID())
- {
- _pCadObject->Select(true);
- continue;
- }
-
- if(_pCadObject->GetType() == caddot)
- {
- _pCadObject->Select();
- }
- else
- {
- _pCadObject->Select(false);
- }
- }
- }
-
- // 平行且长度相等的线为相似图形。 ---- 黄海燕 2015-12-22
- void CSelectTarget::_SelectSimilarLine(const nce::CCadLine* pRefLine_)
- {
- if (!pRefLine_)
- {
- ASSERT(FALSE);
- return;
- }
-
- ASSERT(m_pFileTarget);
- CCadGroup* _pCadGroup = m_pFileTarget->GetCurrentCadGroup();
- for (int _i = 0; _i < _pCadGroup->GetNumOfChild(); _i++)
- {
- CCadObject* _pCadObject = _pCadGroup->GetAt(_i);
- ASSERT(_pCadObject);
- if(_pCadObject->GetType() != cadline)
- {
- _pCadObject->Select(false);
- continue;
- }
-
- // 自己肯定长得像自己,不过这里的前提是每个对象的ID是唯一的。 ---- 黄海燕 2016-01-07
- if (_pCadObject->GetID() == pRefLine_->GetID())
- {
- _pCadObject->Select(true);
- continue;
- }
-
- CCadLine* _pLine = (CCadLine*)_pCadObject;
- DPOINT2 _ptV1 = DPOINT2(_pLine->GetStartPoint() - _pLine->GetEndPoint());
- DPOINT2 _ptV2 = DPOINT2(pRefLine_->GetStartPoint() - pRefLine_->GetEndPoint());
- if (DOUBLE_EQU_ZERO(_ptV1.x * _ptV2.y - _ptV1.y * _ptV2.x)
- && DOUBLE_ROUGHEQU(_ptV1.GetLength(), _ptV2.GetLength()))
- {
- _pLine->Select();
- }
- else
- {
- _pLine->Select(false);
- }
- }
- }
-
- // 半径相等的圆为相似图形。 ---- 黄海燕 2015-12-22
- void CSelectTarget::_SelectSimilarCircle(const nce::CCadCircle* pRefCircle_)
- {
- if (!pRefCircle_)
- {
- ASSERT(FALSE);
- return;
- }
-
- ASSERT(m_pFileTarget);
- CCadGroup* _pCadGroup = m_pFileTarget->GetCurrentCadGroup();
- for (int _i = 0; _i < _pCadGroup->GetNumOfChild(); _i++)
- {
- CCadObject* _pCadObject = _pCadGroup->GetAt(_i);
- ASSERT(_pCadObject);
- if(_pCadObject->GetType() != cadcircle)
- {
- _pCadObject->Select(false);
- continue;
- }
-
- // 自己肯定长得像自己,不过这里的前提是每个对象的ID是唯一的。 ---- 黄海燕 2016-01-07
- if (_pCadObject->GetID() == pRefCircle_->GetID())
- {
- _pCadObject->Select(true);
- continue;
- }
-
- CCadCircle* _pCircle = (CCadCircle*)_pCadObject;
- if (DOUBLE_ROUGHEQU(_pCircle->GetRadius(), pRefCircle_->GetRadius()))
- {
- _pCircle->Select(true);
- }
- else
- {
- _pCircle->Select(false);
- }
- }
- }
-
- // 半径相等长度相等的圆弧为相似图形。 ---- 黄海燕 2015-12-22
- void CSelectTarget::_SelectSimilarArc(const nce::CCadArc* pRefArc_)
- {
- if (!pRefArc_)
- {
- ASSERT(FALSE);
- return;
- }
-
- ASSERT(m_pFileTarget);
- CCadGroup* _pCadGroup = m_pFileTarget->GetCurrentCadGroup();
- for (int _i = 0; _i < _pCadGroup->GetNumOfChild(); _i++)
- {
- CCadObject* _pCadObject = _pCadGroup->GetAt(_i);
- ASSERT(_pCadObject);
- if(_pCadObject->GetType() != cadarc)
- {
- _pCadObject->Select(false);
- continue;
- }
-
- // 自己肯定长得像自己,不过这里的前提是每个对象的ID是唯一的。 ---- 黄海燕 2016-01-07
- if (_pCadObject->GetID() == pRefArc_->GetID())
- {
- _pCadObject->Select(true);
- continue;
- }
-
- CCadArc* _pArc = (CCadArc*)_pCadObject;
- if (DOUBLE_ROUGHEQU(_pArc->GetRadius(), pRefArc_->GetRadius())
- && DOUBLE_ROUGHEQU(_pArc->GetLength(), pRefArc_->GetLength()))
- {
- _pArc->Select(true);
- }
- else
- {
- _pArc->Select(false);
- }
- }
- }
-
- // 长半轴和短半轴相等的椭圆形为相似图形。 ---- 黄海燕 2015-12-22
- void CSelectTarget::_SelectSimilarEllipse(const nce::CCadEllipse* pRefEllipse_)
- {
- if (!pRefEllipse_)
- {
- ASSERT(FALSE);
- return;
- }
-
- ASSERT(m_pFileTarget);
- CCadGroup* _pCadGroup = m_pFileTarget->GetCurrentCadGroup();
- for (int _i = 0; _i < _pCadGroup->GetNumOfChild(); _i++)
- {
- CCadObject* _pCadObject = _pCadGroup->GetAt(_i);
- ASSERT(_pCadObject);
- if(_pCadObject->GetType() != cadellipse)
- {
- _pCadObject->Select(false);
- continue;
- }
-
- // 自己肯定长得像自己,不过这里的前提是每个对象的ID是唯一的。 ---- 黄海燕 2016-01-07
- if (_pCadObject->GetID() == pRefEllipse_->GetID())
- {
- _pCadObject->Select(true);
- continue;
- }
-
- CCadEllipse* _pEllipse = (CCadEllipse*)_pCadObject;
- if ((DOUBLE_ROUGHEQU(_pEllipse->GetLongRadius(), pRefEllipse_->GetLongRadius())
- && DOUBLE_ROUGHEQU(_pEllipse->GetShortRadius(), pRefEllipse_->GetShortRadius())))
- {
- _pEllipse->Select(true);
- }
- else
- {
- _pEllipse->Select(false);
- }
- }
- }
-
- // 长半轴、短半轴、倾斜角、起始角和终止角相等的椭圆弧形为相似图形。 ---- 黄海燕 2015-12-22
- void CSelectTarget::_SelectSimilarEllipseArc(const nce::CCadEllipseArc* pRefEllipseArc_)
- {
- if (!pRefEllipseArc_)
- {
- ASSERT(FALSE);
- return;
- }
-
- ASSERT(m_pFileTarget);
- CCadGroup* _pCadGroup = m_pFileTarget->GetCurrentCadGroup();
- for (int _i = 0; _i < _pCadGroup->GetNumOfChild(); _i++)
- {
- CCadObject* _pCadObject = _pCadGroup->GetAt(_i);
- ASSERT(_pCadObject);
- if(_pCadObject->GetType() != cadellipsearc)
- {
- _pCadObject->Select(false);
- continue;
- }
-
- // 自己肯定长得像自己,不过这里的前提是每个对象的ID是唯一的。 ---- 黄海燕 2016-01-07
- if (_pCadObject->GetID() == pRefEllipseArc_->GetID())
- {
- _pCadObject->Select(true);
- continue;
- }
-
- bool _bSelect = false;
- CCadEllipseArc* _pEllipseArc = (CCadEllipseArc*)_pCadObject;
- if (DOUBLE_ROUGHEQU(_pEllipseArc->GetLongRadius(), pRefEllipseArc_->GetLongRadius())
- && DOUBLE_ROUGHEQU(_pEllipseArc->GetShortRadius(), pRefEllipseArc_->GetShortRadius())
- && DOUBLE_ROUGHEQU(_pEllipseArc->GetCentralAngle(), pRefEllipseArc_->GetCentralAngle()))
- {
- if (DOUBLE_ROUGHEQU(_pEllipseArc->GetStartAngle(), pRefEllipseArc_->GetStartAngle())
- && _pEllipseArc->IsNormalDir() == pRefEllipseArc_->IsNormalDir())
- {
- _bSelect = true;
- }
- if (DOUBLE_ROUGHEQU(_pEllipseArc->GetEndAngle(), pRefEllipseArc_->GetStartAngle())
- && _pEllipseArc->IsNormalDir() == !pRefEllipseArc_->IsNormalDir())
- {
- _bSelect = true;
- }
-
- double _nStartAngle = _pEllipseArc->GetStartAngle() + ncmath::c_nPIE;
- if (_nStartAngle >= 2 * ncmath::c_nPIE)
- {
- _nStartAngle -= 2 * ncmath::c_nPIE;
- }
- if (DOUBLE_ROUGHEQU(_nStartAngle, pRefEllipseArc_->GetStartAngle())
- && _pEllipseArc->IsNormalDir() == pRefEllipseArc_->IsNormalDir())
- {
- _bSelect = true;
- }
- if (DOUBLE_ROUGHEQU(_nStartAngle, pRefEllipseArc_->GetEndAngle())
- && _pEllipseArc->IsNormalDir() == !pRefEllipseArc_->IsNormalDir())
- {
- _bSelect = true;
- }
-
- _nStartAngle = 2 * ncmath::c_nPIE - _pEllipseArc->GetStartAngle();
- if (_nStartAngle >= 2 * ncmath::c_nPIE)
- {
- _nStartAngle -= 2 * ncmath::c_nPIE;
- }
- if (DOUBLE_ROUGHEQU(_nStartAngle, pRefEllipseArc_->GetStartAngle())
- && _pEllipseArc->IsNormalDir() == !pRefEllipseArc_->IsNormalDir())
- {
- _bSelect = true;
- }
- if (DOUBLE_ROUGHEQU(_nStartAngle, pRefEllipseArc_->GetEndAngle())
- && _pEllipseArc->IsNormalDir() == pRefEllipseArc_->IsNormalDir())
- {
- _bSelect = true;
- }
-
- _nStartAngle += ncmath::c_nPIE;
- if (_nStartAngle >= 2 * ncmath::c_nPIE)
- {
- _nStartAngle -= 2 * ncmath::c_nPIE;
- }
- if (DOUBLE_ROUGHEQU(_nStartAngle, pRefEllipseArc_->GetStartAngle())
- && _pEllipseArc->IsNormalDir() == !pRefEllipseArc_->IsNormalDir())
- {
- _bSelect = true;
- }
- if (DOUBLE_ROUGHEQU(_nStartAngle, pRefEllipseArc_->GetEndAngle())
- && _pEllipseArc->IsNormalDir() == pRefEllipseArc_->IsNormalDir())
- {
- _bSelect = true;
- }
- }
- _pEllipseArc->Select(_bSelect);
- }
- }
-
- // 长和宽相等的矩形为相似图形。 ---- 黄海燕 2015-12-22
- void CSelectTarget::_SelectSimilarRectangle(const nce::CCadRectangle* pRefRectangle_)
- {
- if (!pRefRectangle_)
- {
- ASSERT(FALSE);
- return;
- }
-
- ASSERT(m_pFileTarget);
- CCadGroup* _pCadGroup = m_pFileTarget->GetCurrentCadGroup();
- for (int _i = 0; _i < _pCadGroup->GetNumOfChild(); _i++)
- {
- CCadObject* _pCadObject = _pCadGroup->GetAt(_i);
- ASSERT(_pCadObject);
- if(_pCadObject->GetType() != cadrectangle)
- {
- _pCadObject->Select(false);
- continue;
- }
-
- // 自己肯定长得像自己,不过这里的前提是每个对象的ID是唯一的。 ---- 黄海燕 2016-01-07
- if (_pCadObject->GetID() == pRefRectangle_->GetID())
- {
- _pCadObject->Select(true);
- continue;
- }
-
- CCadRectangle* _pRectangle = (CCadRectangle*)_pCadObject;
- if ((DOUBLE_ROUGHEQU(_pRectangle->GetWidth(), pRefRectangle_->GetWidth())
- && DOUBLE_ROUGHEQU(_pRectangle->GetHeitht(), pRefRectangle_->GetHeitht()))
- || (DOUBLE_ROUGHEQU(_pRectangle->GetWidth(), pRefRectangle_->GetHeitht())
- && DOUBLE_ROUGHEQU(_pRectangle->GetHeitht(), pRefRectangle_->GetWidth())))
- {
- _pRectangle->Select(true);
- }
- else
- {
- _pRectangle->Select(false);
- }
- }
- }
-
- // 外接圆半径和内接圆半径相同,定点数相等的正多边形为相似图形。 ---- 黄海燕 2015-12-22
- void CSelectTarget::_SelectSimilarPolygon(const nce::CCadPolygon* pRefPolygon_)
- {
- if (!pRefPolygon_)
- {
- ASSERT(FALSE);
- return;
- }
-
- ASSERT(m_pFileTarget);
- CCadGroup* _pCadGroup = m_pFileTarget->GetCurrentCadGroup();
- for (int _i = 0; _i < _pCadGroup->GetNumOfChild(); _i++)
- {
- CCadObject* _pCadObject = _pCadGroup->GetAt(_i);
- ASSERT(_pCadObject);
- if(_pCadObject->GetType() != cadpolygon)
- {
- _pCadObject->Select(false);
- continue;
- }
-
- // 自己肯定长得像自己,不过这里的前提是每个对象的ID是唯一的。 ---- 黄海燕 2016-01-07
- if (_pCadObject->GetID() == pRefPolygon_->GetID())
- {
- _pCadObject->Select(true);
- continue;
- }
-
- CCadPolygon* _pPolygon = (CCadPolygon*)_pCadObject;
- if (_pPolygon->GetNumOfVertexes() == pRefPolygon_->GetNumOfVertexes()
- && DOUBLE_ROUGHEQU(_pPolygon->GetCircumRadius(), pRefPolygon_->GetCircumRadius())
- && DOUBLE_ROUGHEQU(_pPolygon->GetInscribedRadius(), pRefPolygon_->GetInscribedRadius()))
- {
- _pPolygon->Select(true);
- }
- else
- {
- _pPolygon->Select(false);
- }
- }
- }
-
- // 外接圆半径和内接圆半径相同,定点数相等的星型为相似图形。 ---- 黄海燕 2015-12-22
- void CSelectTarget::_SelectSimilarStar(const nce::CCadStar* pRefStar_)
- {
- if (!pRefStar_)
- {
- ASSERT(FALSE);
- return;
- }
-
- ASSERT(m_pFileTarget);
- CCadGroup* _pCadGroup = m_pFileTarget->GetCurrentCadGroup();
- for (int _i = 0; _i < _pCadGroup->GetNumOfChild(); _i++)
- {
- CCadObject* _pCadObject = _pCadGroup->GetAt(_i);
- ASSERT(_pCadObject);
- if(_pCadObject->GetType() != cadstar)
- {
- _pCadObject->Select(false);
- continue;
- }
-
- // 自己肯定长得像自己,不过这里的前提是每个对象的ID是唯一的。 ---- 黄海燕 2016-01-07
- if (_pCadObject->GetID() == pRefStar_->GetID())
- {
- _pCadObject->Select(true);
- continue;
- }
-
- CCadStar* _pStar = (CCadStar*)_pCadObject;
- if (_pStar->GetNumOfVertexes() == pRefStar_->GetNumOfVertexes()
- && DOUBLE_ROUGHEQU(_pStar->GetCircumRadius(), pRefStar_->GetCircumRadius())
- && DOUBLE_ROUGHEQU(_pStar->GetInscribedRadius(), pRefStar_->GetInscribedRadius()))
- {
- _pStar->Select(true);
- }
- else
- {
- _pStar->Select(false);
- }
- }
- }
-
- // 一模一样的多义线才算相似。 ---- 黄海燕 2015-12-22
- void CSelectTarget::_SelectSimilarPolyline(const nce::CCadPolyline* pRefPolyline_)
- {
- if (!pRefPolyline_)
- {
- ASSERT(FALSE);
- return;
- }
-
- ASSERT(m_pFileTarget);
- CCadGroup* _pCadGroup = m_pFileTarget->GetCurrentCadGroup();
- for (int _i = 0; _i < _pCadGroup->GetNumOfChild(); _i++)
- {
- CCadObject* _pCadObject = _pCadGroup->GetAt(_i);
- ASSERT(_pCadObject);
- if(_pCadObject->GetType() != cadpolyline)
- {
- _pCadObject->Select(false);
- continue;
- }
-
- // 自己肯定长得像自己,不过这里的前提是每个对象的ID是唯一的。 ---- 黄海燕 2016-01-07
- if (_pCadObject->GetID() == pRefPolyline_->GetID())
- {
- _pCadObject->Select(true);
- continue;
- }
-
- // 遍历比较。
- CCadPolyline* _pPolyline = (CCadPolyline*)_pCadObject;
- if (_pPolyline->GetNodeCount() != pRefPolyline_->GetNodeCount()
- || !DOUBLE_ROUGHEQU(_pPolyline->GetLength(), pRefPolyline_->GetLength()))
- {
- _pPolyline->Select(false);
- continue;
- }
-
- if (_pPolyline->GetNodeCount() == 1)
- {
- bool _bSelect = false;
- CCadPolyline::ARCNODE _node = _pPolyline->GetAt(0);
- CCadPolyline::ARCNODE _nodeRef = pRefPolyline_->GetAt(0);
- if (!DOUBLE_EQU_ZERO(_node.nBulge)
- && DOUBLE_ROUGHEQU(_node.nBulge, _nodeRef.nBulge)
- && DOUBLE_ROUGHEQU(_pPolyline->GetLength(), pRefPolyline_->GetLength()))
- {
- _bSelect = true;
- }
-
- DPOINT2 _ptV1 = _node.ptEnd - _pPolyline->GetStartPoint();
- DPOINT2 _ptV2 = _nodeRef.ptEnd - pRefPolyline_->GetStartPoint();
- if (DOUBLE_EQU_ZERO(_node.nBulge)
- && DOUBLE_ROUGHEQU(_node.nBulge, _nodeRef.nBulge)
- && DOUBLE_EQU_ZERO(_ptV1.x * _ptV2.y - _ptV1.y * _ptV2.x))
- {
- _bSelect = true;
- }
- _pPolyline->Select(_bSelect);
- continue;
- }
-
- // 在进行详细的比对之前,我们需要先确认待判断图形与原图形的起点相对位置是否吻合,
- // 是否出现错位(这种情况只有封闭图形会出现)或者顺序颠倒的情况 ---- 陈思 2017-03-17
- bool _bSelect;
- CCadPolyline _RefPolylineCopy = *pRefPolyline_; // 原指针存储的对象是const类型的,这里我们用一个副本拷贝原对象,方便颠倒
- int _nCount = _pPolyline->GetNodeCount();
- int _nDeviationRange = 1;
- // 如果是非封闭图形就不会存在错位现象了,只考虑方向颠倒,偏移范围为1
- if(_pPolyline->IsClose())
- {
- _nDeviationRange = _nCount;
- }
- for(int _nDeviation = 0; _nDeviation < _nDeviationRange; ++_nDeviation)
- {
- _bSelect = true;
- DPOINT2 _ptStart = _pPolyline->GetStartPoint();
- DPOINT2 _ptStartRef;
- if(_nDeviation == 0)
- {
- _ptStartRef = _RefPolylineCopy.GetStartPoint();
- }
- else
- {
- _ptStartRef = (_RefPolylineCopy.GetAt(_nDeviation - 1)).ptEnd;
- }
- // 定义一个控制镜像的开关,未知为0,打开为1,关闭为2
- int _nMirror = 0;
- for(int _i = 1; _i < _nCount; _i++)
- {
- CCadPolyline::ARCNODE _nodeFirst = _pPolyline->GetAt(_i - 1);
- CCadPolyline::ARCNODE _nodeSecond = _pPolyline->GetAt(_i);
-
- CCadPolyline::ARCNODE _nodeRefFirst = _RefPolylineCopy.GetAt((_i - 1 + _nDeviation) % _nCount);
- CCadPolyline::ARCNODE _nodeRefSecond = _RefPolylineCopy.GetAt((_i + _nDeviation) % _nCount);
-
- // 如果绝对值都不相等,那肯定不相似
- if (!DOUBLE_ROUGHEQU(abs(_nodeFirst.nBulge), abs(_nodeRefFirst.nBulge)))
- {
- _bSelect = false;
- break;
- }
-
- // 当状态未知时出现绝对值相等的状况时,如果两个对应点的凸度为相反数,则将镜像开关打开,如果两者相等,则关闭
- // 如果两者都为0,还不能判断出到底是不是镜像,所以_nMirror保持为0不变,进入下一次循环重新判断
- if(_nMirror == 0)
- {
- if(_nodeFirst.nBulge * _nodeRefFirst.nBulge < 0)
- {
- _nMirror = 1;
- }
-
- if(_nodeFirst.nBulge * _nodeRefFirst.nBulge > 0)
- {
- _nMirror = 2;
- }
- continue;
- }
-
- // 在镜像开关打开的时候,如果两个对应点的凸度不等于零且相等,则镜像不成立,跳出
- else if(_nMirror == 1)
- {
- if(_nodeFirst.nBulge * _nodeRefFirst.nBulge > 0)
- {
- _bSelect = false;
- break;
- }
- }
- // 在镜像开关关闭的时候,如果两个对应点的凸度不为零且互为相反数,则不镜像不成立,跳出
- else
- {
- if(_nodeFirst.nBulge * _nodeRefFirst.nBulge < 0)
- {
- _bSelect = false;
- break;
- }
- }
-
- DPOINT2 _ptFirstV = _nodeFirst.ptEnd - _ptStart;
- DPOINT2 _ptSecondV = _nodeSecond.ptEnd - _nodeFirst.ptEnd;
- DPOINT2 _ptFirstVRef = _nodeRefFirst.ptEnd - _ptStartRef;
- DPOINT2 _ptSecondVRef = _nodeRefSecond.ptEnd - _nodeRefFirst.ptEnd;
- if (!DOUBLE_ROUGHEQU(_ptFirstV.GetLength(), _ptFirstVRef.GetLength())
- || !DOUBLE_ROUGHEQU(_ptSecondV.GetLength(), _ptSecondVRef.GetLength()))
- {
- _bSelect = false;
- break;
- }
-
- if (!DOUBLE_ROUGHEQU(ncmath::D2GetIncludeAngle(_ptFirstV, _ptSecondV), ncmath::D2GetIncludeAngle(_ptFirstVRef, _ptSecondVRef)))
- {
- _bSelect = false;
- break;
- }
- _ptStart = _nodeFirst.ptEnd;
- _ptStartRef = _nodeRefFirst.ptEnd;
- }
- if(_bSelect)
- {
- break;
- }
- }
-
- // 如果第一次对比不吻合,则将待判断图形的方向颠倒一次后再比对 ---- 陈思 2017-03-17
- if(!_bSelect)
- {
- _RefPolylineCopy.ReverseDir();
- for(int _nDeviation = 0; _nDeviation < _nCount; ++_nDeviation)
- {
- _bSelect = true;
- DPOINT2 _ptStart = _pPolyline->GetStartPoint();
- DPOINT2 _ptStartRef;
- if(_nDeviation == 0)
- {
- _ptStartRef = _RefPolylineCopy.GetStartPoint();
- }
- else
- {
- _ptStartRef = (_RefPolylineCopy.GetAt(_nDeviation - 1)).ptEnd;
- }
- // 定义一个控制镜像的开关,未知为0,打开为1,关闭为2
- int _nMirror = 0;
- for(int _i = 1; _i < _nCount; _i++)
- {
- CCadPolyline::ARCNODE _nodeFirst = _pPolyline->GetAt(_i - 1);
- CCadPolyline::ARCNODE _nodeSecond = _pPolyline->GetAt(_i);
-
- CCadPolyline::ARCNODE _nodeRefFirst = _RefPolylineCopy.GetAt((_i - 1 + _nDeviation) % _nCount);
- CCadPolyline::ARCNODE _nodeRefSecond = _RefPolylineCopy.GetAt((_i + _nDeviation) % _nCount);
-
-
- // 如果绝对值都不相等,那肯定不相似
- if (!DOUBLE_ROUGHEQU(abs(_nodeFirst.nBulge), abs(_nodeRefFirst.nBulge)))
- {
- _bSelect = false;
- break;
- }
-
- // 当状态未知时出现绝对值相等的状况时,如果两个对应点的凸度为相反数,则将镜像开关打开,如果两者相等,则关闭
- // 如果两者都为0,还不能判断出到底是不是镜像,所以_nMirror保持为0不变,进入下一次循环重新判断
- if(_nMirror == 0)
- {
- if(_nodeFirst.nBulge * _nodeRefFirst.nBulge < 0)
- {
- _nMirror = 1;
- }
-
- if(_nodeFirst.nBulge * _nodeRefFirst.nBulge > 0)
- {
- _nMirror = 2;
- }
- continue;
- }
-
- // 在镜像开关打开的时候,如果两个对应点的凸度不等于零且相等,则镜像不成立,跳出
- else if(_nMirror == 1)
- {
- if(_nodeFirst.nBulge * _nodeRefFirst.nBulge > 0)
- {
- _bSelect = false;
- break;
- }
- }
- // 在镜像开关关闭的时候,如果两个对应点的凸度不为零且互为相反数,则不镜像不成立,跳出
- else
- {
- if(_nodeFirst.nBulge * _nodeRefFirst.nBulge < 0)
- {
- _bSelect = false;
- break;
- }
- }
-
- DPOINT2 _ptFirstV = _nodeFirst.ptEnd - _ptStart;
- DPOINT2 _ptSecondV = _nodeSecond.ptEnd - _nodeFirst.ptEnd;
- DPOINT2 _ptFirstVRef = _nodeRefFirst.ptEnd - _ptStartRef;
- DPOINT2 _ptSecondVRef = _nodeRefSecond.ptEnd - _nodeRefFirst.ptEnd;
- if (!DOUBLE_ROUGHEQU(_ptFirstV.GetLength(), _ptFirstVRef.GetLength())
- || !DOUBLE_ROUGHEQU(_ptSecondV.GetLength(), _ptSecondVRef.GetLength()))
- {
- _bSelect = false;
- break;
- }
-
- if (!DOUBLE_ROUGHEQU(ncmath::D2GetIncludeAngle(_ptFirstV, _ptSecondV), ncmath::D2GetIncludeAngle(_ptFirstVRef, _ptSecondVRef)))
- {
- _bSelect = false;
- break;
- }
- _ptStart = _nodeFirst.ptEnd;
- _ptStartRef = _nodeRefFirst.ptEnd;
- }
- if(_bSelect)
- {
- break;
- }
- }
- }
- _pPolyline->Select(_bSelect);
- }
- }
-
- // 给定的选择框是否选择到图形,区分正选和反选 ---- DingQiang 2011-12-9
- BOOL CSelectTarget::_SelectCadObjectByRect(const nce::CCadObject* pCadObject_,
- const DPOINT2& ptFirst_,
- const DPOINT2& ptSecond_)
- {
- ASSERT(pCadObject_);
- DRECT _rcSelect(ptFirst_, ptSecond_); // 选择框矩形
- DRECT _rcBound = pCadObject_->GetBoundRect(); // 图形外接矩形
-
- // 如果选择框完全包围图形,则不区分正反选择返回TRUE ---- DingQiang 2011-12-9
- if (_rcSelect.Contains(_rcBound))
- {
- return TRUE;
- }
-
- // 如果选择框没有完全包围图形,则区分正反选。如果为正选择则反回FALSE ---- DingQiang 2011-12-9
- if (ptSecond_.x >= ptFirst_.x)
- {
- return FALSE;
- }
-
- // 如果为反选,则判断选择框和图形的外接矩形是否相交,如果不相交则返回FALSE,由于
- // 水平的线段和垂直的线段外接矩与选择框一定没有交点,所以使宽高增加一点几乎可
- // 忽略的长度,以方便判断其与选择框是否相交 ---- DingQiang 2011-12-9
- if (_rcBound.width == 0)
- {
- _rcBound.width = 1.0e-9;
- }
-
- if (_rcBound.height == 0)
- {
- _rcBound.height = 1.0e-9;
- }
-
- if (!_rcSelect.Intersect(_rcBound))
- {
- return FALSE;
- }
-
- // 如果为负选且选择框和图形的外接矩形相交,则判断选择框是否和图形相交。先
- // 根据选择框矩形构造一个CAD矩形,再调用GetIntersection函数判断是否与图形
- // 有交点。 ---- DingQiang 2011-12-9
- DPOINT2 _ptPoint0 = ptFirst_;
- DPOINT2 _ptPoint1(ptFirst_.x, ptSecond_.y);
- DPOINT2 _ptPoint2 = ptSecond_;
- DPOINT2 _ptPoint3(ptSecond_.x, ptFirst_.y);
- CCadRectangle _CadRectangle(_ptPoint0, _ptPoint1, _ptPoint2, _ptPoint3);
-
- int _nIntersectionCounts = GetIntersection(&_CadRectangle, pCadObject_, NULL);
- return (_nIntersectionCounts > 0);
- }
-
- BOOL CSelectTarget::SelectRefLine(const DPOINT2& point_, double nTolerance_)
- {
- ASSERT(m_pFileTarget);
- CCadGroup* _pRefLines = m_pFileTarget->GetCurrentRefLines();
- if (!_pRefLines || _pRefLines->IsEmpty())
- return FALSE;
-
- // 参考线只能选中一个,选择第二个则会清除其他参考线的选中状态 Wanglou 2010-08-21
- int _nCount = _pRefLines->GetNumOfChild();
- for (int _i = 0; _i < _nCount; _i++)
- _pRefLines->GetAt(_i)->Select(false);
-
- CCadObject* _pCadObject = Hit(_pRefLines, point_, nTolerance_);
- if (!_pCadObject)
- return FALSE;
-
- // 所有参考线都为直线,如果选择了参考线,则所有的Cad对象的选择状态都会清除 Wanglou 2010-08-21
- ASSERT(_pCadObject->GetType() == cadbeeline);
- ClearSelect();
- _pCadObject->Select(true);
- return TRUE;
- }
-
- // 全选
- void CSelectTarget::SelectAll()
- {
- ASSERT(m_pFileTarget);
- CCadGroup* _pCadGroup = m_pFileTarget->GetCurrentCadGroup();
- if (_pCadGroup->IsEmpty())
- return;
- const CadObjectList* _pCadObjList = _pCadGroup->GetObjectsList();
- bool _bChanged = false;
-
- // 先清除 ---- DingQiang 2013-09-23
- m_listSelectedCadObjects.clear();
- for (CadObjectList::const_iterator _iter = _pCadObjList->begin(); _iter != _pCadObjList->end(); _iter++)
- {
- m_listSelectedCadObjects.push_back(*_iter);
- if (!(*_iter)->IsSelected())
- {
- (*_iter)->Select(true);
- _bChanged = true;
- }
- }
- }
-
- // 反选
- void CSelectTarget::SelectRev()
- {
- // 反转各对象的选中状态 ---- 杨开锦 2011-07-18
- ASSERT(m_pFileTarget);
- CCadGroup* _pCadGroup = m_pFileTarget->GetCurrentCadGroup();
- for (int _i = 0; _i < _pCadGroup->GetNumOfChild(); _i++)
- {
- CCadObject* _pCad = _pCadGroup->GetAt(_i);
- ASSERT(_pCad);
- bool _bSelected = _pCad->IsSelected();
- _pCad->Select(!_bSelected);
- }
-
- // 更新选中对象链表 ---- 杨开锦 2011-07-18
- GetSelectedCadObjects(true);
- }
-
- // 清空
- void CSelectTarget::ClearSelect()
- {
- ASSERT(m_pFileTarget);
- CCadGroup* _pCadGroup = m_pFileTarget->GetCurrentCadGroup();
- if (_pCadGroup && !_pCadGroup->IsEmpty())
- {
- // 清除Cad对象的选中状态
- const CadObjectList* _pCadObjList = _pCadGroup->GetObjectsList();
- for (CadObjectList::const_iterator _iter = _pCadObjList->begin(); _iter != _pCadObjList->end(); _iter++)
- {
- if ((*_iter)->IsSelected())
- (*_iter)->Select(false);
- }
- m_listSelectedCadObjects.clear();
- }
-
- // 清除参考线的选中状态
- CCadGroup* _pRefLines = m_pFileTarget->GetCurrentRefLines();
- if (_pRefLines && !_pRefLines->IsEmpty())
- {
- int _nCount = _pRefLines->GetNumOfChild();
- for (int _i = 0; _i < _nCount; _i++)
- _pRefLines->GetAt(_i)->Select(false);
- }
- }
-
- const CadObjectList* CSelectTarget::GetSelectedCadObjects(bool bArbitrary_/* = false*/)
- {
- // 若为强制更新,则从FileTarget中重新收集 ---- 杨开锦 2011-06-10
- if (bArbitrary_)
- {
- m_listSelectedCadObjects.clear();
-
- ASSERT(m_pFileTarget);
- CCadGroup* _pCadGroup = m_pFileTarget->GetCurrentCadGroup();
- ASSERT(_pCadGroup);
- int _nCount = _pCadGroup->GetNumOfChild();
- for (int _i = 0; _i < _nCount; _i++)
- {
- CCadObject* _pCadObject = _pCadGroup->GetAt(_i);
- ASSERT(_pCadObject);
- if (_pCadObject->IsSelected())
- {
- m_listSelectedCadObjects.push_back(_pCadObject);
- }
- }
- }
-
- return &m_listSelectedCadObjects;
- }
-
- const nce::CadObjectList* CSelectTarget::GetSelectedRefLines(bool bArbitrary_/* = false*/)
- {
- // 若为强制更新,则从FileTarget中重新收集 ---- 杨开锦 2011-06-10
- if (bArbitrary_)
- {
- m_listSelectedRefLines.clear();
-
- ASSERT(m_pFileTarget);
- CCadGroup* _pCadGroup = m_pFileTarget->GetCurrentRefLines();
- ASSERT(_pCadGroup);
- int _nCount = _pCadGroup->GetNumOfChild();
- for (int _i = 0; _i < _nCount; _i++)
- {
- CCadObject* _pCadObject = _pCadGroup->GetAt(_i);
- ASSERT(_pCadObject);
- if (_pCadObject->IsSelected())
- {
- m_listSelectedRefLines.push_back(_pCadObject);
- }
- }
- }
-
- return &m_listSelectedRefLines;
- }
-
- void CSelectTarget::Reset()
- {
- m_ptLButtonDown = DPOINT2(c_nINVALID_DOUBLE, c_nINVALID_DOUBLE);
- m_ptTemp = DPOINT2(c_nINVALID_DOUBLE, c_nINVALID_DOUBLE);
- }
-
- DRECT CSelectTarget::GetSelObjsBoundRect(bool bArbitrary_/* = false*/)
- {
- // bArbitrary_为true时强制更新缓存。 ---- 杨开锦 2011-06-16
- if (bArbitrary_)
- {
- // 初始化
- const CadObjectList* _plistSelObjs = GetSelectedCadObjects();
- ASSERT(_plistSelObjs);
- DRECT _rcTotalRect(c_nINVALID_DOUBLE, c_nINVALID_DOUBLE, c_nINVALID_DOUBLE, c_nINVALID_DOUBLE);
-
- // 计算
- for (CadObjectList::const_iterator _it = _plistSelObjs->begin(); _it != _plistSelObjs->end(); _it++)
- {
- DRECT _rect = (*_it)->GetBoundRect();
- if (_it == _plistSelObjs->begin())
- _rcTotalRect = _rect;
- else
- DRECT::Union(_rcTotalRect, _rcTotalRect, _rect);
- }
-
- // 保存
- m_rcSelObjsBoundRect = _rcTotalRect;
- }
-
- return m_rcSelObjsBoundRect;
- }
-
- DRECT CSelectTarget::GetObjsBoundRect(const CadObjectList* pObjectsList_)
- {
- if (!pObjectsList_ || pObjectsList_->empty())
- DRECT(0,0,0,0);
-
- DRECT _rc;
- for (CadObjectList::const_iterator _iter = pObjectsList_->begin(); _iter != pObjectsList_->end(); _iter++)
- {
- DRECT _rect = (*_iter)->GetBoundRect();
- if (_iter == pObjectsList_->begin())
- _rc = _rect;
- else
- DRECT::Union(_rc, _rc, _rect);
- }
-
- return _rc;
- }
-
- void CSelectTarget::SetRButtonMenu_NoneSelected(CMenu* pRButtonMenu_)
- {
- ASSERT(pRButtonMenu_);
- ASSERT(pRButtonMenu_->GetSafeHmenu());
- m_pRButtonMenu_NoneSelected = pRButtonMenu_;
- }
-
- void CSelectTarget::SetRButtonMenu_SingleSelected(CMenu* pRButtonMenu_)
- {
- ASSERT(pRButtonMenu_);
- ASSERT(pRButtonMenu_->GetSafeHmenu());
- m_pRButtonMenu_SingleSelected = pRButtonMenu_;
- }
-
- void CSelectTarget::SetRButtonMenu_MultiSelected(CMenu* pRButtonMenu_)
- {
- ASSERT(pRButtonMenu_);
- ASSERT(pRButtonMenu_->GetSafeHmenu());
- m_pRButtonMenu_MultiSelected = pRButtonMenu_;
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // Local function implementations
- //
- // 根据一个给定的观察窗,将给定的一组CAD对象划分为以下三个部分,划分的判断办法是
- // 求对象的外接矩形,然后用外接矩形的包含和相交关系来判断。
- // FullInside : 对象完全在观察窗内
- // PartInside : 对象部分在观察窗内
- // NotInside : 对象完全不在观察窗内
- // 观察窗ViewPort应为有效,即其位置点应为有效,宽高应为非负。三个用于OUT的指针均
- // 可以为NULL,为NULL时表示不需要收集这一部分的对象。 ---- 杨开锦 2011-07-16
- static void _DivideObjectsIntoThree(IN const CadObjectList* plistSource_,
- IN const DRECT& rcViewport_,
- OUT CadObjectList* plistFullInside_,
- OUT CadObjectList* plistPartInside_,
- OUT CadObjectList* plistNotInside_)
- {
- ASSERT(plistSource_);
- ASSERT(IsValidDouble(rcViewport_.x) && IsValidDouble(rcViewport_.y)
- && rcViewport_.width >= 0. && rcViewport_.height >= 0);
-
- if (!plistFullInside_ && !plistPartInside_ && !plistNotInside_)
- {
- return;
- }
-
- for (CadObjectList::const_iterator _it = plistSource_->begin();
- _it != plistSource_->end(); _it++)
- {
- // 求外接矩形 ---- 杨开锦 2011-07-16
- CCadObject* _pCadObject = *_it;
- ASSERT(_pCadObject);
- DRECT _rcBound = _pCadObject->GetBoundRect();
-
- // 先判断包含关系,再判断相交关系 ---- 杨开锦 2011-07-16
- if (rcViewport_.Contains(_rcBound))
- {
- if (plistFullInside_)
- plistFullInside_->push_back(_pCadObject);
- }
- else if (rcViewport_.IntersectsWith(_rcBound))
- {
- if (plistPartInside_)
- plistPartInside_->push_back(_pCadObject);
- }
- else
- {
- if (plistNotInside_)
- plistNotInside_->push_back(_pCadObject);
- }
- }
- }
-
- LRESULT CSelectTarget::SelectAll(WPARAM wParam_, LPARAM lParam_)
- {
- ASSERT(m_pFileTarget);
- CCadGroup* _pCadGroup = m_pFileTarget->GetCurrentCadGroup();
- if (_pCadGroup->IsEmpty())
- return FALSE;
- const CadObjectList* _pCadObjList = _pCadGroup->GetObjectsList();
-
- // 先清除 ---- DingQiang 2013-09-23
- m_listSelectedCadObjects.clear();
- for (CadObjectList::const_iterator _iter = _pCadObjList->begin(); _iter != _pCadObjList->end(); _iter++)
- {
- m_listSelectedCadObjects.push_back(*_iter);
- if (!(*_iter)->IsSelected())
- {
- (*_iter)->Select(true);
- }
- }
-
- return TRUE;
- }
|