////////////////////////////////////////////////////////////////////////////// #include #include #include #include "StdAfx.h" #include ".\itemselect.h" #include "Util.h" #include "SigmaDoc.h" #include "SigmaView.h" #include ".\itemcircle.h" #include ".\itempointEdit.h" #include ".\itemmesh.h" //#include "ChartLib\TypeDefine.h" #include "PlatBase/CommonDefine.h" #include "ItemTracker.h" #include "SigmaView.h" #include "ItemGrid.h" #include "ItemProportion.h" #include "ItemGrid.h" #include "ActionDeleteItem.h" #include "DCHelp.h" #include "ActionListItem.h" #include "Actionadditem.h" #include "actionmoveitem.h" #include "ActionMoveItemSelected.h" #include ".\actionmarkdeleteitem.h" #include "ActionOffsetItem.h" //#include "ActionBackupItem.h" //#include ".\actionoffsetitem.h" #include "VoronoiMap/InterfaceElements.h" #include "VoronoiMap/voronoimap.h" #include "pointsubset.h" #include //fbw #include "Item.h" #include "StatusDefine.h" #include "DrawOperator/CurveUtil.h" #include "clipper2/clipper.h" #define DELAUNAY "Delaunay" // 三角网 #define VORONOI "Voronoi" // 龟背图 using namespace Clipper2Lib; /** * 将 CPolyline 折线 转换为 自定义的折线类 * * \param pCurve * \return */ static CPolyline CurveExToPolyline(CCurveEx * pCurve) { CPolyline polyline; polyline.SetName(pCurve->GetName()); for (int i = 0; i < pCurve->num; i++) { polyline.AddPoint(pCurve->x[i], pCurve->y[i], pCurve->z[i]); } return polyline; } /** * 将 自定义的折线类 转换为 CPolyline 折线 * * \param pCurve * \return */ static CCurveEx* PolylineToCurveEx(CPolyline & polyline) { CCurveEx *pCurve = new CCurveEx(); int iCount = polyline.GetSize(); pCurve->SetName(polyline.GetName()); pCurve->Create(iCount); for (int i = 0; i < iCount; i++) { CPointXYZ &xyz = polyline.GetPoint(i); pCurve->x[i] = xyz.x0; pCurve->y[i] = xyz.y0; pCurve->z[i] = xyz.z0; } return pCurve; } /** * \param point * \return */ static CPointXYZ CPointNameExToCPointXYZ(CPointNameEx &point) { CPointXYZ pointXYZ; pointXYZ.x0 = point.x0; pointXYZ.y0 = point.y0; pointXYZ.z0 = point.z0; pointXYZ.SetName(point.GetName()); return pointXYZ; } //#define GetQTracker() GetDoc()->GetTracker() void GSD_Select(CSigmaDoc * doc, int mouseX, int mouseY) { CItemSelect * select = new CItemSelect(doc); doc->SetItem(select); CPoint pt(mouseX, mouseY); select->OnLButtonDown(nullptr,1, pt, 0); select->OnLButtonUp(nullptr, 0, pt); } // 在GDI+中,有关字符的参数类型全部都是WCHAR类型的,该函数是将传统字符串进行转换 WCHAR* ToWChar(char* str) { static WCHAR buffer[1024]; _wcsset(buffer, 0); MultiByteToWideChar(CP_ACP,0,str,(int)strlen(str),buffer,1024); return buffer; } char* ToChar(const WCHAR* str) { static char dest[1024]; _strset(dest, 0); WideCharToMultiByte(CP_ACP, 0, str, -1, dest, (int)wcslen(str), NULL, NULL ); return dest; } CItemSelect::CItemSelect(CSigmaDoc * ppDoc) : CItemFocusRect(ppDoc) , nDragHandle(0) , m_pItemForGrid(NULL) , IsSelectionChanged(FALSE) , m_bTrackerEnable(true) , m_isLocationChanged(false) , m_bEnableRotate(false) { this->SetType(ITEM_SELECT); selectMode = selnone; m_bPointTextSelected=FALSE; } CItemSelect::~CItemSelect(void) { DeleteItemGrid(); } void CItemSelect::OnDraw(CXyDC* pXyDC, CDC* pDC) { if (!m_bTrackerEnable) return; ASSERT(GetDoc()); //ReloadTrackerPath(); m_Tracker.m_bEnableRotate = this->m_bEnableRotate; m_Tracker.Draw(pDC); GetDC()->Create(pDC); //画曲线节点 CSize sz = GetDoc()->GetHandleSize(); CPoint pt1, pt2; CCurveEx* pc; int i, j; for (COne *pOne : SelectionCones()) { switch (pOne->GetType()) { case WELL_GROUP: break; case DOUBLEFOX_CURVE: pc = (CCurveEx*)pOne->GetValue(); j = 0; for (i = 0; i < pc->num; i++) { pt1 = GetDC()->GetScreen(pc->x[i], pc->y[i]); if (i == 0 || i == pc->num - 1) { GetDoc()->DrawHandle(pc->x[i], pc->y[i], TRACKER_NO_EDIT, pDC); } else { pt2 = GetDC()->GetScreen(pc->x[j], pc->y[j]); if (abs(pt1.x - pt2.x) > sz.cx || abs(pt1.y - pt2.y) > sz.cy) { GetDoc()->DrawHandle(pc->x[i], pc->y[i], TRACKER_NO_EDIT, pDC); j = i; } } } break; case DOUBLEFOX_XYZ: case DOUBLEFOX_POINT: break; default: break; } } } void CItemSelect::OnDraw(CXyDC* pDC) { if (!m_bTrackerEnable) return; ASSERT(GetDoc()); m_Tracker.Draw(GetDC()->GetDC()); //画曲线节点 CSize sz = GetDoc()->GetHandleSize(); CPoint pt1, pt2; CCurveEx* pc; int i, j; for (COne *pOne : SelectionCones()) { switch (pOne->GetType()) { case DOUBLEFOX_CURVE: pc = (CCurveEx*)pOne->GetValue(); j = 0; for (i = 0; i < pc->num; i++) { pt1 = GetDC()->GetScreen(pc->x[i], pc->y[i]); if (i == 0 || i == pc->num - 1) { //GetDoc()->DrawHandle(pc->x[i], pc->y[i], TRACKER_NO_EDIT); } else { pt2 = GetDC()->GetScreen(pc->x[j], pc->y[j]); if (abs(pt1.x - pt2.x) > sz.cx || abs(pt1.y - pt2.y) > sz.cy) { //GetDoc()->DrawHandle(pc->x[i], pc->y[i], TRACKER_NO_EDIT); j = i; } } } break; case DOUBLEFOX_XYZ: case DOUBLEFOX_POINT: break; default: break; } } } /** * 判断曲线是否是闭合区域 */ static bool IsCurveClosed(CCurveEx* pBlock) { if (pBlock->num < 3) { return false; } int lastIndex = pBlock->num - 1; return pBlock->x[0] == pBlock->x[lastIndex] && pBlock->y[0] == pBlock->y[lastIndex] && pBlock->z[0] == pBlock->z[lastIndex]; } int CItemSelect::CreateVoronoiMap(POSITION& posCurve, CPositionList& addCurveList) { CXy* pXyD = GetDoc()->GetDraw(); COne* pOne = pXyD->GetAt(posCurve); // 这是手工绘制的边框线,把点圈起来的那部分连线 CCurveEx* pBlock = (CCurveEx*)pOne->GetValue(); CCurveEx* pNewBlock = nullptr; // 如果曲线没有闭合,我们主动给它闭合 if (!IsCurveClosed(pBlock)) { pNewBlock = CreateCloseCurve(pBlock); if (pNewBlock == nullptr) { return 0; } pBlock = pNewBlock; } // 1、获取断层和井 // 获取区域内的断层 std::list flts = CollectFlts(pBlock); // 获取区域内的井 std::vector wells = CollectWells(pBlock); if (wells.size() <= 0) { return 0; } for (auto itFlt = flts.begin(); itFlt != flts.end();) { CCurveEx* pCurve = *itFlt; for (auto it = wells.begin(); it != wells.end();) { CWellPoint ptWell = *it; if (pCurve->IsInside(ptWell.x0, ptWell.y0)) { it = wells.erase(it); } else { ++it; } } ++itFlt; } // 2、绘制三角网或龟背图 CPolyline border = CurveExToPolyline(pBlock); std::list results; CString layerName; int nRst = 0; layerName = VORONOI; std::list lstFaultLine; for (auto it = flts.begin(); it != flts.end();) { // 将单线断层缓冲成闭合断层 CCurveEx* pCurve = *it; double dLength = pCurve->Length(); if (dLength < 0.001) { it = flts.erase(it); continue; } dfPoint ptStart, ptEnd; pCurve->GetPoint(0, ptStart); pCurve->GetPoint(pCurve->num - 1, ptEnd); double dDist = ptStart.Distance(ptEnd); if (dDist > dLength*0.1) { PathD path; for (int i = 0; i < pCurve->num; i++) { path.emplace_back(pCurve->x[i], pCurve->y[i]); } PathsD pathsFault; pathsFault.push_back(path); PathsD solution = Clipper2Lib::InflatePaths(pathsFault, dDist*0.01, JoinType::Miter, EndType::Square); if (solution.size() > 1) { int iFind = 0; double dLengthMax = 0; int nIndexSolu = 0; for (auto itPath = solution.begin(); itPath != solution.end(); itPath++) { double dLethTemp = 0; size_t sizePath = (*itPath).size(); for (size_t i = 1; i < sizePath; ++i) { const Clipper2Lib::PointD& pt1 = (*itPath)[i - 1]; const Clipper2Lib::PointD& pt2 = (*itPath)[i]; const double dx = pt2.x - pt1.x; const double dy = pt2.y - pt1.y; dLethTemp += dx * dx + dy * dy; } dLethTemp += (pow(((*itPath)[0].x - (*itPath)[sizePath - 1].x),2) + pow(((*itPath)[0].y - (*itPath)[sizePath - 1].y), 2)); if (dLethTemp > dLengthMax) { dLengthMax = dLethTemp; iFind = nIndexSolu; } nIndexSolu++; } PathD pathBuf = solution[iFind]; CPolyline plyFaultBuf; size_t sizePath = pathBuf.size(); for (size_t i = 0; i < sizePath; ++i) { const Clipper2Lib::PointD& pt = pathBuf[i]; plyFaultBuf.AddPoint(pt.x, pt.y, 0); } //plyFaultBuf.AddPoint(pathBuf[0].x, pathBuf[0].y,0); lstFaultLine.push_back(plyFaultBuf); } else { //CPolyline plyFaultBuf; CCurveEx* curveOne = new CCurveEx; CPointList ptsFault; PathD pathBuf = solution[0]; for (auto itPly = pathBuf.begin(); itPly != pathBuf.end();) { NBase::dfPoint point; point.x0 = itPly->x; point.y0 = itPly->y; ptsFault.AddTail(point); itPly++; } NBase::dfPoint pointEnd; pointEnd.x0 = ptsFault.GetHead().x0; pointEnd.y0 = ptsFault.GetHead().y0; ptsFault.AddTail(pointEnd); //} curveOne->SetName("Fault"); curveOne->SetPoints(ptsFault, 2, 0); POSITION pos = pXyD->AddElement(curveOne, DOUBLEFOX_CURVE); COne* pOne = pXyD->GetAt(pos); CLayer* pLayerFault = pXyD->FindAddLayer("断层"); pOne->SetLayer(pLayerFault); //COne* pOne = pXyD->CreateOne(&curveOne, DOUBLEFOX_CURVE); //pOne->SetLayer(pLayerFault); //pXyD->AddTailOne(pOne); CPolyline plyFault = CurveExToPolyline(curveOne); lstFaultLine.push_back(plyFault); } it++; continue; } CPolyline plyFault = CurveExToPolyline(pCurve); lstFaultLine.push_back(plyFault); it++; } nRst = DrawVorono(lstFaultLine, wells, border, &results); // 3、将结果绘制到图层上 DrawResultToLayer(layerName, results, addCurveList); if (pNewBlock != nullptr) { delete pNewBlock; } return nRst; } int CItemSelect::CreateDelaunayMap() { CXy* pXy = GetDoc()->GetDraw(); CPositionList lstVoronoiAll; int nCount = 0; COne* pOne; for (POSITION pos = (m_selection).GetHeadPosition(); pos != nullptr; (m_selection).GetNext(pos)) { POSITION pt = m_selection.GetAt(pos); pOne = pXy->GetAt(pt); if (pOne->GetType() == DOUBLEFOX_CURVE) { nCount += CreateDelaunayMap(pt, lstVoronoiAll); } } // 添加撤销 if (nCount > 0) { CActionAddItem * pAction = new CActionAddItem(GetDoc(), ID_OPERATOR_CREATE_VORONOI, lstVoronoiAll); GetDoc()->SetActionItem(pAction); } return nCount; } int NItem::CItemSelect::CreateDelaunayMap(POSITION& posCurve, CPositionList& addCurveList) { CXy* pXy = GetDoc()->m_pXy; COne* pOne = pXy->GetAt(posCurve); // 这是手工绘制的边框线,把点圈起来的那部分连线 CCurveEx* pBlock = (CCurveEx*)pOne->GetValue(); CCurveEx* pNewBlock = nullptr; // 如果曲线没有闭合,我们主动给它闭合 if (!IsCurveClosed(pBlock)) { pNewBlock = CreateCloseCurve(pBlock); if (pNewBlock == nullptr) { return 0; } pBlock = pNewBlock; } // 1、获取断层和井 // 获取区域内的断层 std::list flts = CollectFlts(pBlock); std::list lstPlyFault; for (auto it = flts.begin(); it != flts.end();) { CPolyline plyFlt = CurveExToPolyline(*it); lstPlyFault.push_back(plyFlt); it++; } // 获取区域内的井 std::vector wells = CollectWells(pBlock); if (wells.size() <= 0) { return 0; } // 2、绘制三角网 CPolyline border = CurveExToPolyline(pBlock); std::list results; CString layerName; int nRst = 0; layerName = DELAUNAY; nRst = DrawDelaunay(lstPlyFault, wells, border, &results); // 3、将结果绘制到图层上 DrawResultToLayer(layerName, results, addCurveList); if (pNewBlock != nullptr) { delete pNewBlock; } return nRst; } int CItemSelect::CreateVoronoiMap() { CXy* pXy = GetDoc()->GetDraw(); CPositionList lstVoronoiAll; int nCount = 0; COne* pOne; for (POSITION pos = (m_selection).GetHeadPosition(); pos != nullptr; (m_selection).GetNext(pos)) { POSITION pt = m_selection.GetAt(pos); pOne = pXy->GetAt(pt); if (pOne->GetType() == DOUBLEFOX_CURVE) { nCount += CreateVoronoiMap(pt, lstVoronoiAll); } } // 添加撤销 if (nCount > 0) { CActionAddItem * pAction = new CActionAddItem(GetDoc(), ID_OPERATOR_CREATE_VORONOI, lstVoronoiAll); GetDoc()->SetActionItem(pAction); } return nCount; } int CItemSelect::SimplifySelectPoints(double minSpacing) { std::vector pointXYZs; if (m_selection.IsEmpty()) { SetStatusCode(STATUS_CODE_SELECT_SELECT_NOTHING); SetStatusText(STATUS_TEXT_SELECT_SELECT_NOTHING); return 0; } std::vector polygons = CollectPolygons(); if (!polygons.empty()) { pointXYZs = GetPointsInCurves(polygons); } else { pointXYZs = SelectedPointXYZs(); } if (pointXYZs.empty()) { SetStatusCode(STATUS_CODE_SELECT_NO_POINT_SELECT); SetStatusText(STATUS_TEXT_SELECT_NO_POINT_SELECT); DeleteAll(polygons); return 0; } // 抽稀 CPointSubset pointSubset; pointSubset.ReadPoints(pointXYZs); std::vector reservedIdx; std::vector removedIdx; pointSubset.CreateSubsetWithMinDist(minSpacing, reservedIdx, &removedIdx); std::vector removedPoints; for (size_t i = 0; i < pointXYZs.size(); i++) { if (Contains(removedIdx, (int)i)) { removedPoints.push_back(pointXYZs[i]); } } // 找到需要剔除的点 CPositionList needRemoved; FindNeedRemovePoints(removedPoints, needRemoved); // 删除 if (!needRemoved.IsEmpty()) { // 如果是空的,没必要压一个 Action 过去,尽管这里不跳过,它依然也正常执行 CActionDeleteItem * deleteItem = new CActionDeleteItem(GetDoc(), IDS_STRING_ACTION_DELETE, needRemoved); GetDoc()->SetActionItem(deleteItem); } DeleteAll(polygons); return (int)needRemoved.GetCount(); } void CItemSelect::OnLButtonDblClk(UINT nFlags, CPoint point) { } void CItemSelect::OnLButtonDown(CDC *pDC, UINT nFlags, CPoint point, int vk) { m_isLocationChanged = false; IsTransformFirst = TRUE; //TRACE("OnLButtonDown:HandleNothing-1:m_Handle=%d\n", GetQTracker().m_Handle); CPoint2D dp = GetDC()->GetReal(point); selectMode = selnone; //bool bShift = (nFlags & MK_SHIFT) != 0 ? true : false; bool bControl = ::IsKeyDown(VK_CONTROL) || vk== VK_CONTROL; //当按下Alt键时进行元素的顺序选择 bool bAlt = ::IsKeyDown(VK_MENU); //int handle = -1; int nSel = GetCountSelected(); //TRACE("OnLButtonDown:HandleNothing-2:m_Handle=%d\n", GetQTracker().m_Handle); QTransformTracker::Handle hitHandle = (QTransformTracker::Handle)m_Tracker.HitTest(point); if (hitHandle == QTracker::Handle::HandleNothing) { c_down = dp; c_last = dp; m_IsFocusing = FALSE; m_Tracker.CanDrawCenter = TRUE; // Click on background, start a net-selection if (selectMode == selnone) { m_bPointTextSelected = FALSE; if (!bControl && !bAlt) { //ClearAll(pDC); } selectMode = netSelect; return; } } if (nSel > 0 && bControl) { try { if (hitHandle != QTracker::Handle::HandleNothing) { c_down = dp; c_last = dp; m_IsFocusing = FALSE; m_Tracker.CanDrawCenter = TRUE; m_bPointTextSelected = FALSE; if (!bControl && !bAlt) { //ClearAll(pDC); } selectMode = netSelect; return; } } catch (...) { TRACE0("erafsd"); } } if (nSel > 0 && !bAlt && !bControl) // As long as an object is selected... { try { if (hitHandle != QTracker::Handle::HandleNothing) { int r = m_Tracker.OnBeginTrack(nFlags, point); // 如果是准备移动,生成移动轮廓图 if (m_Tracker.m_Mode == QTracker::Mode::TransformMove) { //CRect rect = m_Tracker.m_StartRect; } //c_down = dp; //c_last = dp; //m_IsFocusing = FALSE; //m_Tracker.CanDrawCenter = TRUE; //m_bPointTextSelected = FALSE; //if (!bShift && !bAlt) { // //ClearAll(pDC); //} //selectMode = netSelect; return; } } catch (...) { TRACE0("erafsd"); } } c_down = dp; c_last = dp; } BOOL CItemSelect::OnMoving() { return (m_Tracker.m_Mode == QTracker::Mode::TransformMove); } CRect CItemSelect::GetTrackerRect() { return m_Tracker.m_StartRect; } void CItemSelect::DrawTrackPath(CDC* pDC) { m_Tracker.DrawFull(pDC, QTracker::UpdateMode::UpdateMouseFlags | QTracker::UpdateMode::UpdateDraw | QTracker::UpdateMode::UpdateEnter); } void CItemSelect::OnLButtonUp(CDC *pDC, UINT nFlags, CPoint point, int vk) { // 清空选择集 注意;不能在构造函数中调用此函数 因为有些操作还要依赖之前的选择结果 如镜像操作 if (m_Tracker.SetTrackModeOnClick(0, point) == TRUE) { if (pDC != nullptr) { m_Tracker.Draw(pDC); } } GetDoc()->ReplaceSelectionSet(m_selection); //TRACE("OnLButtonUp:m_Handle=%d\n", m_Tracker.m_Handle); if (m_Tracker.m_TrackResult == QTracker::TrackResult::TrackContinue) { m_Tracker.OnEndTrack(QTracker::TrackResult::TrackSucceeded); IsTransformFirst = TRUE; m_Tracker.m_TrackResult = QTracker::TrackResult::TrackSucceeded; int nResult = EndTransformSelection(nFlags, point, m_Tracker.m_Handle); if (nResult > 0) { m_isLocationChanged = true; } // this->OnDraw(GetDC(), pDC); return; } // 当按下Shift键时进行多选 // bool bShift=(nFlags&MK_SHIFT )!=0 ? true:false; bool bControl = ::IsKeyDown(VK_CONTROL) || (vk == VK_CONTROL); // 当按下Alt键时进行元素的顺序选择 bool bAlt = ::IsKeyDown(VK_MENU); if (!bAlt) { if (selectMode != netSelect && bControl == FALSE) { return; } selectMode = selnone; } // 消除选择框 CItemFocusRect::OnLButtonUp(pDC, nFlags, point, vk); CRect8 rect=GetRect(); m_lastRect = rect; // 在鼠标抬起时选择元素 if(rect.IsEmpty()) { // See if the click was on an object, select and start move if so CPoint2D dp = GetDC()->GetReal(point); //POSITION posObj=GetDoc()->GetSelectedItem(dp); POSITION pt=NULL; POSITION posObj=NULL; if(bAlt && GetCountSelected()==1)//为了按下Alt键进行挖掘元素 { pt=m_selection.GetHead(); int type=GetDoc()->GetDraw()->GetElementType(pt); if( type==DOUBLEFOX_POINT || type == DOUBLEFOX_XYZ) { COne* pOne=GetDoc()->GetDraw()->GetAt(pt); CPointNameEx* ppn=(CPointNameEx*)pOne->GetValue(); CRect8 range(1e100,-1e100,-1e100,1e100); ppn->GetRangeText(range, pOne->GetHowToViewPoint()); //为了选择点元素做准备, 是选择整个元素还是仅选择文本部分 m_bPointTextSelected=range.PtInRect(dp); if(m_bPointTextSelected) posObj=pt; else posObj=GetDoc()->GetNextSelectedItem(dp,pt); } else posObj=GetDoc()->GetNextSelectedItem(dp,pt); } else { posObj = GetDoc()->GetNextSelectedItem(dp, pt); } //return; if (posObj != NULL) //选中图元 { //选择元素 selectMode = move; if (!IsSelected(posObj)) Select(posObj, bControl, dp); else if (bControl) Deselect(posObj); //ReloadTrackerPath(); //this->OnDraw(GetDC(), pDC); } else if (!bControl){ ClearAll(pDC); } } else { SelectWithinRect(rect, bControl); } ReloadTrackerPath(); //if (!m_selection.IsEmpty()) // m_Tracker.Create(m_pDoc, m_selection); //else // m_Tracker.Reset(); //if (GetCountSelected()>0) //{ //this->OnDraw(GetDC(), pDC); //} //this->OnDraw(GetDC(), pDC); //ReleaseCapture(); } int CItemSelect::OnMouseMove(CDC *pDC,UINT nFlags, CPoint point) { if (selectMode == netSelect) { CItemFocusRect::OnMouseMove(pDC, nFlags, point); } else if (m_Tracker.m_TrackResult == QTracker::TrackResult::TrackContinue) { if (m_Tracker.m_Mode == QTracker::Mode::TransformMove) { m_Tracker.OnMouseMessage(0, nFlags, point); return 1; } m_Tracker.CanDrawCenter = FALSE; //TRACE("before->CItemSelect::OnMouseMove:m_Handle=%d\n", GetQTracker().m_Handle); int nOldRop = pDC->SetROP2(R2_NOTXORPEN); if (IsTransformFirst == TRUE) { m_Tracker.OnMouseMessage(0, nFlags, point); m_Tracker.OnUpdate(pDC, QTracker::UpdateMode::UpdateMouseFlags | QTracker::UpdateMode::UpdateDraw | QTracker::UpdateMode::UpdateLeave); } else { m_Tracker.OnUpdate(pDC, QTracker::UpdateMode::UpdateMouseFlags | QTracker::UpdateMode::UpdateRemove | QTracker::UpdateMode::UpdateEnter); m_Tracker.OnMouseMessage(0, nFlags, point); m_Tracker.OnUpdate(pDC, QTracker::UpdateMode::UpdateMouseFlags | QTracker::UpdateMode::UpdateDraw | QTracker::UpdateMode::UpdateLeave); } pDC->SetROP2(nOldRop); IsTransformFirst = FALSE; } return 1; } void CItemSelect::MoveElementsTo(CPoint point) { m_Tracker.OnMouseMessage(0, 0, point); GetDoc()->ReplaceSelectionSet(m_selection); m_Tracker.OnEndTrack(QTracker::TrackResult::TrackSucceeded); IsTransformFirst = TRUE; m_Tracker.m_TrackResult = QTracker::TrackResult::TrackSucceeded; int nResult = EndTransformSelection(0, point, m_Tracker.m_Handle); if (nResult > 0) { m_isLocationChanged = true; } } void CItemSelect::OnRButtonDown(UINT nFlags, CPoint point) { } BOOL CItemSelect::OnSetCursor(CPoint pt, int& handle) { if (m_Tracker.m_TrackResult == QTracker::TrackResult::TrackContinue) { return FALSE; } // See if QTransformTracker wants to handle this message //BOOL b = FALSE; handle = m_Tracker.OnSetCursor(GetScreenDC(), pt); //if (!b) //{ // GetDoc()->GetCursor().SetCursor(CursorSelect); // GetDoc()->GetCursor().SetCursor(); // return TRUE; //} return TRUE; } int CItemSelect::EndTransformSelection(UINT nFlags, CPoint point, int handle) { // ... start a tracking operation. //CDC* pScreenDC = GetScreenDC(); //int r = GetQTracker().Track(pScreenDC, nFlags, point); int r = m_Tracker.m_TrackResult; if (r == QTracker::TrackCancelled) return r; if (r <= 0) return r; // tracking operation succeeded int mode = m_Tracker.NormalizeHit(handle); //设置旋转圆心时直接返回 if (mode == QTransformTracker::TransformCenter) return r; InvalidateSelection(); float elements[6]; memset(elements, 0, sizeof(float) * 6); // Get the transformation Matrix Gdiplus::Matrix * pMat = m_Tracker.GetTransform(); if (pMat->IsIdentity())//单位矩阵 { delete pMat; return r; } if (pMat->GetElements(elements) != Ok) { delete pMat; return QTracker::TrackCancelled; } delete pMat;// Not needed anymore UINT nMatrixID = 0; switch (mode) { case QTransformTracker::TransformMove: // Ctrl+Click clones and the selection...and select clones if (m_Tracker.IsCopy()) { nMatrixID = IDS_STRING_MATRIX_CLONE; CloneSelection(); } else nMatrixID = IDS_STRING_ACTION_MOVE; break; case QTransformTracker::TransformScale: nMatrixID = IDS_STRING_MATRIX_SCALE; break; case QTransformTracker::TransformRotate: nMatrixID = IDS_STRING_MATRIX_ROTATE; break; case QTransformTracker::TransformShear: nMatrixID = IDS_STRING_MATRIX_SHEAR; break; } if (nMatrixID == 0) return r; CActionListItem* pActionItem = new CActionListItem(GetDoc(), nMatrixID); //GetDoc()->BeginProgress("Transform..."); if (TransformSelection(elements, mode, pActionItem)) { GetDoc()->Modified(); } // GetDoc()->EndProgress(); // for redo/undo surport if (m_Tracker.IsCopy()) { GetDoc()->SetActionItem(new CActionAddItem(GetDoc(), nMatrixID, m_selection)); delete pActionItem; } else { GetDoc()->SetActionItem(pActionItem); } //reload selection path,and UpdateAllViews ReloadTrackerPath(); return r; } BOOL CItemSelect::TransformSelection(float* matrix, int nMode, void* pActionItem) { CActionListItem* ppActionItem = (CActionListItem*)pActionItem; CPositionList ml; BOOL bIsCopy = m_Tracker.IsCopy(); BOOL br = TRUE; for (POSITION pos = m_selection.GetHeadPosition(); pos != nullptr; m_selection.GetNext(pos)) { POSITION pt = m_selection.GetAt(pos); COne* pOne = GetDoc()->GetDraw()->GetAt(pt); switch (pOne->GetType()) { case DOUBLEFOX_XYZ: case DOUBLEFOX_POINT: if (m_bPointTextSelected || (!IsCanMoveCoor(pOne) && !bIsCopy)) //当设定为坐标不能移动时 { //ppActionItem->AddBackupItem(pOne); CPointNameEx* ppn = (CPointNameEx*)pOne->GetValue(); CRect8 range(1e100, -1e100, -1e100, 1e100); ppn->GetRangeText(range, pOne->GetHowToViewPoint()); CPoint2D center = range.CenterPoint(); range.SetRect(center.x0, center.y0, center.x0, center.y0); pOne->Transform(&GetDoc()->GetDC(), matrix, range.right, range.bottom, FALSE); if (pOne->HowToViewPoint == NULL) { pOne->HowToViewPoint = new CHowToViewPoint; if (pOne->GetLayer()->HowToViewPoint) //层修饰 *(pOne->HowToViewPoint) = *(pOne->GetLayer()->HowToViewPoint); } pOne->HowToViewPoint->m_delt.cx += range.Width(); pOne->HowToViewPoint->m_delt.cy -= range.Height(); } else { if (pOne->Transform(&GetDoc()->GetDC(), matrix)) ml.AddTail(pt); } br = TRUE; break; case DOUBLEFOX_IMAGE: if (nMode == QTransformTracker::TransformRotate || nMode == QTransformTracker::TransformShear) { ppActionItem->AddBackupItem(pOne); } else ml.AddTail(pt); switch (nMode) { case QTransformTracker::TransformRotate: case QTransformTracker::TransformShear: if (pOne->TransformImage(&GetDoc()->GetDC(), matrix, FALSE) != 0)break; case QTransformTracker::TransformMove: case QTransformTracker::TransformScale: { CImageInsert* pImage = (CImageInsert*)pOne->GetValue(); double x1 = pImage->x0 + pImage->m_size.cx; double y1 = pImage->y0 + pImage->m_size.cy; pOne->Transform(&GetDoc()->GetDC(), matrix, pImage->x0, pImage->y0, FALSE); pOne->Transform(&GetDoc()->GetDC(), matrix, x1, y1, FALSE); pImage->m_size.SetSize(x1 - pImage->x0, y1 - pImage->y0); } break; } br = TRUE; break; case DOUBLEFOX_CRECT: if (nMode == QTransformTracker::TransformRotate || nMode == QTransformTracker::TransformShear) { ppActionItem->AddBackupItem(pOne); CCurveEx* pc = new CCurveEx; ((CCurveRect*)pOne->GetValue())->GetCurve(*pc); pOne->ClearValue(); pOne->SetValue(pc, DOUBLEFOX_CURVE); pOne->Transform(&GetDoc()->GetDC(), matrix); } else if (pOne->Transform(&GetDoc()->GetDC(), matrix)) ml.AddTail(pt); br = TRUE; break; case DOUBLEFOX_ELLIPSE: if (nMode == QTransformTracker::TransformRotate || nMode == QTransformTracker::TransformShear) { ppActionItem->AddBackupItem(pOne); CCurveEx* pc = ((CEllipse*)pOne->GetValue())->ToCurve(2.0); pOne->ClearValue(); pOne->SetValue(pc, DOUBLEFOX_CURVE); pOne->Transform(&GetDoc()->GetDC(), matrix); } else if (pOne->Transform(&GetDoc()->GetDC(), matrix)) ml.AddTail(pt); br = TRUE; break; case DOUBLEFOX_ARC: if (nMode == QTransformTracker::TransformRotate || nMode == QTransformTracker::TransformShear) { ppActionItem->AddBackupItem(pOne); ((CArc*)pOne->GetValue())->GetCurve(2.0); CCurveEx* pc = new CCurveEx; *pc = *((CArc*)pOne->GetValue())->GetCurve(); pOne->ClearValue(); pOne->SetValue(pc, DOUBLEFOX_CURVE); pOne->Transform(&GetDoc()->GetDC(), matrix); } else if (pOne->Transform(&GetDoc()->GetDC(), matrix)) ml.AddTail(pt); br = TRUE; break; case DOUBLEFOX_WELLDATAGRAPH://产能柱对象限制不能移动 br = FALSE; break; default: if (pOne->Transform(&GetDoc()->GetDC(), matrix)) { ml.AddTail(pt); br = TRUE; } break; } } if (ml.GetCount() > 0) { CActionMoveItemSelected* pAction = new CActionMoveItemSelected(GetDoc(), 0, ml, matrix); // TODO: 这里没有这一句造成撤销有问题 pAction->SetDC(&(GetDoc()->GetDC())); ppActionItem->AddTailItem(pAction); } return br; } void CItemSelect::CloneSelection() { //COleObjectEx::m_pActiveDocument=GetDoc(); COne *pOne,*pNewOne; POSITION pos,pt,pnew; CList list; pos = m_selection.GetHeadPosition(); while (pos != NULL) { pt = m_selection.GetNext(pos); pOne=(COne*)GetDoc()->GetDraw()->GetAt(pt); pNewOne=new COne(); *pNewOne=*pOne; // copies object and adds it to the document pnew=GetDoc()->GetDraw()->AddTailOne(pNewOne); list.AddTail(pnew); } Select(NULL,FALSE); pos=list.GetHeadPosition(); while(pos) { pt=list.GetNext(pos); Select(pt,TRUE); } ReloadTrackerPath(); } int CItemSelect::DeleteSelection(void) { if(GetItemForGrid()) this->DeleteItemGrid(); //GetDoc()->InvalidateDelete(m_selection); if (m_selection.IsEmpty()) return 0; int nReturn = m_selection.GetSize(); CActionDeleteItem * deleteItem = new CActionDeleteItem(GetDoc(), IDS_STRING_ACTION_DELETE, m_selection); GetDoc()->SetActionItem(deleteItem); m_selection.RemoveAll(); m_Tracker.Clear(); return nReturn; } void CItemSelect::ReversalSelectAll(void) { CPositionList list; CPtrList* pl=GetDoc()->GetDraw()->GetValueList(); POSITION pos=pl->GetHeadPosition(); COne *pOne; while(pos) { if(!IsSelected(pos)) { pOne=(COne *)pl->GetAt(pos); if(pOne->GetLayer()->IsViewAndEdit()) { list.AddTail(pos); } } pl->GetNext(pos); } Select(list,FALSE); GetDoc()->Invalidate(); } //0为全不在范围内,1为全在范围内,2为部分在部分不在范围内 int CItemSelect::CurveInRegion(CCurveEx* pCurve, CCurveEx* pRgn) { ASSERT(pCurve); ASSERT(pRgn); CCrossList cross; pCurve->Cross(*(CCurve*)pRgn, cross); CPoint3D point(pCurve->x[0], pCurve->y[0], 0); if (cross.GetCount() == 1) //为了删除打断后的曲线,如果被删除的曲线的端点正好落在范围线上时 { CCrossPoint pt = cross.GetHead(); if (pCurve->l[0] < pCurve->l[pCurve->num - 1]) { if (fabs(pt.x[0] - pCurve->l[0]) < 1e-10 || fabs(pCurve->l[pCurve->num - 1] - pt.x[0]) < 1e-10) cross.RemoveAll(); } else { if (fabs(pCurve->l[0] - pt.x[0]) < 1e-10 || fabs(pt.x[0] - pCurve->l[pCurve->num - 1]) < 1e-10) cross.RemoveAll(); } if (cross.IsEmpty()) pCurve->GetCoordinate((pCurve->l[0] + pCurve->l[pCurve->num - 1])*0.5, point.x0, point.y0, point.z0); //计算曲线中点 } else if (cross.GetCount() == 2) { CCrossPoint head = cross.GetHead(); CCrossPoint tail = cross.GetTail(); if (pCurve->l[0] < pCurve->l[pCurve->num - 1]) { if (fabs((pCurve->l[pCurve->num - 1] - pCurve->l[0]) - (tail.x[0] - head.x[0])) < 1e-10) cross.RemoveAll(); } else { if (fabs((pCurve->l[0] - pCurve->l[pCurve->num - 1]) - (tail.x[0] - head.x[0])) < 1e-10) cross.RemoveAll(); } if (cross.IsEmpty()) pCurve->GetCoordinate((pCurve->l[0] + pCurve->l[pCurve->num - 1])*0.5, point.x0, point.y0, point.z0); //计算曲线中点 } if (cross.IsEmpty()) { if (pRgn->IsInside(point.x0, point.y0)) return 1; else return 0; } return 2; } int CItemSelect::IsInside(CCurveEx* pRgn, CRect8& rgnRange, COne* pOne) { int bInRgn = 0; switch (pOne->GetType()) { case DOUBLEFOX_TEXT: { CText* pText = (CText*)pOne->GetValue(); if (rgnRange.PtInRect(pText->x0, pText->y0)) bInRgn = pRgn->IsInside(pText->x0, pText->y0); } case DOUBLEFOX_XYZ: case DOUBLEFOX_POINT: { CPointNameBase* pPoint = (CPointNameBase*)pOne->GetValue(); if (rgnRange.PtInRect(pPoint->x0, pPoint->y0)) bInRgn = pRgn->IsInside(pPoint->x0, pPoint->y0); } break; case DOUBLEFOX_CURVE: { CCurveEx* pCurve = (CCurveEx*)pOne->GetValue(); //0为全不在范围内,1为全在范围内,2为部分在部分不在范围内 bInRgn = CurveInRegion(pCurve, pRgn); } break; case DOUBLEFOX_ARC: { CArc* pc = (CArc*)pOne->GetValue(); CCurveEx* pCurve = pc->GetCurve(); //bInRgn = CurveInRegion(pCurve, pRgn); } break; case DOUBLEFOX_CIRCLE: case DOUBLEFOX_ELLIPSE: { CEllipse* pc = (CEllipse*)pOne->GetValue(); CCurveEx* pCurve = pc->ToCurve(1.0); bInRgn = CurveInRegion(pCurve, pRgn); delete pCurve; } break; default: { CRect8 rt = pOne->GetRect(); CCurveEx* pCurve = new CCurveEx; pCurve->CreateCurveFromRect(&rt); bInRgn = CurveInRegion(pCurve, pRgn); delete pCurve; } break; } return bInRgn; } // 选择完全包含在选定区域的图元 int CItemSelect::SelectInCurve() { if (m_selection.GetCount() == 0) { return 0; } POSITION posCurrent, pos, p; posCurrent = m_selection.GetHead(); COne *pOne = (COne*)GetDoc()->GetDraw()->GetAt(posCurrent); CRect8 range = pOne->GetRect(); CCurveEx* pRgn = (CCurveEx*)(pOne->value); if (pOne->GetType() == DOUBLEFOX_CURVE) { Select(NULL, FALSE); // 查找范围内图元 CPositionList list; CPtrList* pl = GetDoc()->GetDraw()->GetValueList(); pos = pl->GetHeadPosition(); COne *pOne; while (pos) { p = pos; pOne = (COne*)pl->GetNext(pos); if (p == posCurrent)continue; if (!pOne->IsCanEdit() || !pOne->IsView()) continue; int bInRgn = IsInside(pRgn, range, pOne); if (bInRgn == 1) { list.AddTail(p); } } Select(list, FALSE); return list.GetCount(); } return 0; } // 选择完全包含在选定区域的图元 int CItemSelect::SelectInCurve(int elementType) { if (m_selection.GetCount() == 0) { return 0; } POSITION posCurrent, pos, p; posCurrent = m_selection.GetHead(); COne *pOne = (COne*)GetDoc()->GetDraw()->GetAt(posCurrent); CRect8 range = pOne->GetRect(); CCurveEx* pRgn = (CCurveEx*)(pOne->value); if (pOne->GetType() == DOUBLEFOX_CURVE) { Select(NULL, FALSE); // 查找范围内图元 CPositionList list; CPtrList* pl = GetDoc()->GetDraw()->GetValueList(); pos = pl->GetHeadPosition(); COne *pOne; while (pos) { p = pos; pOne = (COne*)pl->GetNext(pos); if (p == posCurrent)continue; if (pOne->GetType() != elementType) { continue; } if (!pOne->IsCanEdit() || !pOne->IsView()) continue; int bInRgn = IsInside(pRgn, range, pOne); if (bInRgn == 1) { list.AddTail(p); } } Select(list, FALSE); return list.GetCount(); } return 0; } // 选择完全包含的图元和与选择区域叠超面积超过图元面积一定百分比的图元 int CItemSelect::SelectInCurveEx(double factor) { if (m_selection.GetCount() == 0) { return 0; } POSITION posCurrent, pos, p; posCurrent = m_selection.GetHead(); // 获取选择的边界对象 COne *pRangeOne = (COne*)GetDoc()->GetDraw()->GetAt(posCurrent); CRect8 rectRange = pRangeOne->GetRect(); CCurveEx* pRangeCurveEx = nullptr; COne *pTargetOne = nullptr; CCurveEx* pTargetCurveEx = nullptr; double areaRation = 0; double intersectionArea = 0; double srcArea = 0; CCurveUtil *pCu = new CCurveUtil(); // 选定的图元列表 CPositionList list; CPtrList* pl = GetDoc()->GetDraw()->GetValueList(); CCurveEx* pTempCurve = nullptr; if (pRangeOne->GetType() == DOUBLEFOX_CURVE) { // 获取边界曲线 pRangeCurveEx = (CCurveEx*)(pRangeOne->value); // 取消所有已选择的对象 Select(NULL, FALSE); pos = pl->GetHeadPosition(); while (pos) { p = pos; // 获取图件中的图元 pTargetOne = (COne*)pl->GetNext(pos); // 如果源对象与目标对象是同一个对象跳过 if (p == posCurrent)continue; //如果目标对象不可编辑或不可见跳过 if (!pTargetOne->IsCanEdit() || !pTargetOne->IsView()) continue; // 目标对象是否在源对象范围内 int bInRgn = IsInside(pRangeCurveEx, rectRange, pTargetOne); // 边界包含目标对象 if (bInRgn == 1) { list.AddTail(p); } // 目标对象与源对象相交 if (bInRgn == 2) { if (pTargetOne->GetType() != DOUBLEFOX_CURVE) { continue; } pTargetCurveEx = (CCurveEx*)pTargetOne->GetValue(); intersectionArea = pCu->CalcIntersectionArea(pTargetOne, pRangeOne); srcArea = pTargetCurveEx->Area(); areaRation = intersectionArea / srcArea; if (areaRation > factor) { list.AddTail(p); } } } if (pCu) { delete pCu; pCu = nullptr; } // 选中所有目标对象 Select(list, FALSE); return list.GetCount(); } return 0; } // 选择完全包含的图元和与选择区域叠超面积超过图元面积一定百分比的图元 int CItemSelect::SelectInCurveEx(int elementType, double factor) { if (m_selection.GetCount() == 0) { return 0; } POSITION posCurrent, pos, p; posCurrent = m_selection.GetHead(); // 获取选择的边界对象 COne *pRangeOne = (COne*)GetDoc()->GetDraw()->GetAt(posCurrent); CRect8 rectRange = pRangeOne->GetRect(); CCurveEx* pRangeCurveEx = nullptr; COne *pTargetOne = nullptr; CCurveEx* pTargetCurveEx = nullptr; double areaRation = 0; double intersectionArea = 0; double srcArea = 0; CCurveUtil *pCu = new CCurveUtil(); // 选定的图元列表 CPositionList list; CPtrList* pl = GetDoc()->GetDraw()->GetValueList(); CCurveEx* pTempCurve = nullptr; if (pRangeOne->GetType() == DOUBLEFOX_CURVE) { // 获取边界曲线 pRangeCurveEx = (CCurveEx*)(pRangeOne->value); // 取消所有已选择的对象 Select(NULL, FALSE); pos = pl->GetHeadPosition(); while (pos) { p = pos; // 获取图件中的图元 pTargetOne = (COne*)pl->GetNext(pos); // 如果源对象与目标对象是同一个对象跳过 if (p == posCurrent)continue; if (pTargetOne->GetType() != elementType) { continue; } //如果目标对象不可编辑或不可见跳过 if (!pTargetOne->IsCanEdit() || !pTargetOne->IsView()) continue; // 目标对象是否在源对象范围内 int bInRgn = IsInside(pRangeCurveEx, rectRange, pTargetOne); // 边界包含目标对象 if (bInRgn == 1) { list.AddTail(p); } // 目标对象与源对象相交 if (bInRgn == 2) { if (pTargetOne->GetType() != DOUBLEFOX_CURVE) { continue; } pTargetCurveEx = (CCurveEx*)pTargetOne->GetValue(); intersectionArea = pCu->CalcIntersectionArea(pTargetOne, pRangeOne); srcArea = pTargetCurveEx->Area(); areaRation = intersectionArea / srcArea; if (areaRation > factor) { list.AddTail(p); } } } if (pCu) { delete pCu; pCu = nullptr; } // 选中所有目标对象 Select(list, FALSE); return list.GetCount(); } return 0; } int CItemSelect::SelectSamePropertyElements() { if (m_selection.GetCount() == 0) { return 0; } // 选定的图元列表 CPositionList list; vector vecSelect; vector vecSelectType; vector vecSelectPos; POSITION posSelect = m_selection.GetHeadPosition(); POSITION ptSelect; COne* pOneSelect = nullptr; while (posSelect) { ptSelect = m_selection.GetNext(posSelect); pOneSelect = GetDoc()->GetDraw()->GetAt(ptSelect); CString strView; MakeViewData(pOneSelect, strView); if (!strView.IsEmpty()) { vecSelect.push_back(strView); vecSelectType.push_back(pOneSelect->GetType()); vecSelectPos.push_back(ptSelect); } } int nViewCount = (int)vecSelect.size(); if (nViewCount == 0) { return 0; } CPtrList* plDoc = GetDoc()->GetDraw()->GetValueList(); POSITION posDoc, posFindDoc; posDoc = plDoc->GetHeadPosition(); COne *pTargetOne = nullptr; while (posDoc) { posFindDoc = posDoc; // 获取图件中的图元 pTargetOne = (COne*)plDoc->GetNext(posDoc); CHowToViewCurve* pViewCurve = pTargetOne->GetHowToViewCurve(); CHowToViewPoint* pViewPoint = pTargetOne->GetHowToViewPoint(); int nTypeDoc = pTargetOne->GetType(); if (pViewCurve == nullptr&& pViewPoint == nullptr) { continue; } CString strView; MakeViewData(pTargetOne, strView); for (int i = 0; i < nViewCount; i++) { if (nTypeDoc != vecSelectType[i]) { continue; } if (posFindDoc == vecSelectPos[i]) { continue; } if (strView == vecSelect[i]) { list.AddTail(posFindDoc); break; } } } // 选中所有目标对象 Select(list, TRUE); return list.GetCount(); } void NItem::CItemSelect::MakeViewData(COne * pOneSelect, CString &strSelect) { CHowToViewCurve* pViewCurveSel = pOneSelect->GetHowToViewCurve(); CHowToViewPoint* pViewPointSel = pOneSelect->GetHowToViewPoint(); int nLeng = 0; if (pViewCurveSel != nullptr) { BYTE* pBuffer; pViewCurveSel->WriteMemory(pBuffer, nLeng, 1); CString strData((char*)pBuffer, nLeng); free(pBuffer); strSelect += strData; } if (pViewPointSel != nullptr) { BYTE* pBuffer; pViewPointSel->WriteMemory(pBuffer, nLeng, 1); CString strData((char*)pBuffer, nLeng); free(pBuffer); strSelect += strData; } } int CItemSelect::SelectByNames(CString& data) { CStringArray strNames; int startPos = 0; int commaPos = data.Find(',', startPos); while (commaPos != -1) { CString subStr = data.Mid(startPos, commaPos - startPos); strNames.Add(subStr); startPos = commaPos + 1; commaPos = data.Find(',', startPos); } // 添加最后一个子串 CString lastSubStr = data.Mid(startPos); strNames.Add(lastSubStr); Select(NULL, FALSE); // 查找分隔后的字符串 for (int i = 0; i < strNames.GetSize(); i++) { CString subStr = strNames.GetAt(i); // 处理每个分隔后的子字符串 if (subStr.GetLength() == 0) { continue; } CPtrList* pl = GetDoc()->GetDraw()->GetValueList(); COne *pOne; POSITION pos = pl->GetHeadPosition(); while (pos) { pOne = (COne *)pl->GetAt(pos); if (pOne->GetLayer()->IsViewAndEdit()) { CString name; name = pOne->GetName(); if (name.Find(subStr) >= 0) { m_selection.AddTail(pos); } } pl->GetNext(pos); } } ReloadTrackerPath(); int nCount = m_selection.GetCount(); if (nCount > 0) { POSITION posSelect = m_selection.GetHeadPosition(); POSITION pt; pt = m_selection.GetNext(posSelect); COne* pOneSelect = GetDoc()->GetDraw()->GetAt(pt); CRect8 rect = pOneSelect->GetRect(); while (posSelect) { pt = m_selection.GetNext(posSelect); pOneSelect = GetDoc()->GetDraw()->GetAt(pt); pOneSelect->GetRange(rect); } CRect rt = m_pDoc->GetView()->m_client; GetDoc()->GetDC().Extend(rect, rt, EXTEND_MODE_DEFAULT); } return nCount; } void CItemSelect::SelectAll() { Select(NULL,FALSE); CPtrList* pl=GetDoc()->GetDraw()->GetValueList(); COne *pOne; POSITION pos=pl->GetHeadPosition(); while(pos) { pOne=(COne *)pl->GetAt(pos); if(pOne->GetLayer()->IsViewAndEdit()) { m_selection.AddTail(pos); } pl->GetNext(pos); } ReloadTrackerPath(); //GetDoc()->Invalidate(); } void CItemSelect::SelectAll(UINT nElementType, BOOL bAdd) { if(!bAdd) Select(NULL,FALSE); GetDoc()->GetDraw()->GetElement(nElementType, m_selection); //GetDoc()->Invalidate(); ReloadTrackerPath(); } void CItemSelect::Select(POSITION posObj, BOOL bAdd) { m_Tracker.SetRotateState(false); if (m_selection.IsEmpty() && posObj == NULL) { IsSelectionChanged = false; return; } IsSelectionChanged = true; // PushUndo();//当需要保存UNDO操作时,保存 if (!bAdd) { m_selection.RemoveAll(); } if (posObj == NULL) return; if (m_selection.Find(posObj)) return; m_selection.AddTail(posObj); GetDoc()->ReplaceSelectionSet(m_selection); } void CItemSelect::ClearAll(CDC* pDC) { Select(NULL); if (GetView()) { m_Tracker.Clear(pDC); } } void CItemSelect::Select(POSITION posObj, BOOL bAdd, CPoint2D& point) { m_Tracker.SetRotateState(false); if(m_selection.IsEmpty() && posObj==NULL) return; //if(posObj==NULL || bAdd) { Select(posObj, bAdd); return; } //为了直接能移动井位的名称 //switch(GetDoc()->GetDraw()->GetElementType(posObj)) //{ //case DOUBLEFOX_POINT: // { // COne* pOne=GetDoc()->GetDraw()->GetAt(posObj); // CPointNameEx* pn=(CPointNameEx*)pOne->GetValue(); // CRect8 rt; // pn->GetRangeText(rt, pOne->GetHowToViewPoint()); // if(rt.PtInRect(point)) // { // ::AfxMessageBox("okok"); // } // else // Select(posObj, bAdd); // } // break; //default: // Select(posObj, bAdd); // break; //} } void CItemSelect::ReloadTrackerPath(void) { //CWaitCursor wc; m_Tracker.Clear(); if (m_selection.IsEmpty()) return; POSITION pos, pt; pos = m_selection.GetHeadPosition(); while (pos != NULL) { pt = m_selection.GetNext(pos); LoadPath(pt); } /*if (!m_selection.IsEmpty()) m_tracker.Create(m_pDoc, m_selection);*/ //InvalidateSelection(); } void CItemSelect::LoadPath(POSITION pos) { if (pos == NULL) return; COne* pOne; pOne = (COne*)GetDoc()->GetDraw()->GetAt(pos); LoadPath(pOne); } void CItemSelect::LoadPath(COne* pOne) { if (pOne == NULL) return; GraphicsPath path; path.Reset(); BOOL bNeedRect = TRUE; switch (pOne->GetType()) { case DOUBLEFOX_CURVE: LoadCurvePath(path, (CCurveEx*)pOne->GetValue()); bNeedRect = FALSE; break; case DOUBLEFOX_CIRCLE: case DOUBLEFOX_ELLIPSE: { CEllipse* pCircle = (CEllipse*)pOne->GetValue(); CRect8 range = pOne->GetRect(); CRect rt = GetDC()->GetScreen(range); rt.NormalizeRect(); path.AddEllipse(rt.left, rt.top, rt.Width(), rt.Height()); } break; //case DOUBLEFOX_DONUT: // { // CDonut* pDonut=(CDonut*)pOne->GetValue(); // double r; // r=pDonut->m_size.cy; // CRect8 rt(pDonut->x0-r,pDonut->y0-r,pDonut->x0+r,pDonut->y0+r); // CRect rect=GetDC()->GetScreen(rt); // rect.NormalizeRect(); // path.AddEllipse(rect.left,rect.top,rect.Width(),rect.Height()); // r=pDonut->r1; // rt.SetRect(pDonut->x0-r,pDonut->y0-r,pDonut->x0+r,pDonut->y0+r); // rect=GetDC()->GetScreen(rt); // rect.NormalizeRect(); // path.AddEllipse(rect.left,rect.top,rect.Width(),rect.Height()); // } // break; case DOUBLEFOX_FRAME: { m_posRect = pOne->GetRect(); m_posRect.NormalizeRect(); LoadRectPath(path, m_posRect); //bNeedRect = FALSE; //内边框 // CFrame* pf=(CFrame*)pOne->GetValue(); // m_posRect.SetRect(pf->x0,pf->y0+pf->height,pf->x0+pf->width,pf->y0);m_posRect.NormalizeRect(); // LoadRectPath(path,m_posRect); } break; case DOUBLEFOX_ARC: LoadCurvePath(path, ((CArc*)pOne->GetValue())->GetCurve()); break; case DOUBLEFOX_TEXT: { // pOne 获取的范围不准,它依赖图件存储的 m_size,这里在内存 DC 里面绘制一下,是为了重新计算文字长度 CText* pText = (CText*)pOne->GetValue(); CXyDC* pXyDC = GetDC(); CDC* pBakDC = pXyDC->GetDC(); CRect BakRT = GetDC()->GetViewRect(); std::unique_ptr pImageDC = std::make_unique(); CSize sizeOld; sizeOld.cx = BakRT.Width(); sizeOld.cy = BakRT.Height(); if (!pImageDC->Create(sizeOld)) { return; } pXyDC->Create(pImageDC.get()); // 获得范围 CPoint point; point.x = pXyDC->GetSX(pText->x0); point.y = pXyDC->GetSY(pText->y0); CRect rect(point, point); CFont font; font.CreateFontIndirect(&pText->m_logFont); pImageDC->SelectObject(&font); CString name = RemoveSuperSubscript(pText->GetName()); CString script = GetSuperSubscript(pText->GetName()); // 用 没有上下标的内容 - 上下标文字长度的三分之一 来获取文字框长度,这是考虑到文字有上下标的情况 // 这个算法不准确,比如上标后马上接一个下标,这时上下标内容前部是重叠显示的,是个临时解决方案 pImageDC->DrawText(name, rect, DT_CALCRECT); CRect scriptRect(point, point); pImageDC->DrawText(script, scriptRect, DT_CALCRECT); rect.right = rect.right - (scriptRect.Width() / 3); pXyDC->Create(pBakDC); CRect8 rt8 = pXyDC->GetReal(rect); rt8.NormalizeRect(); pText->Aligns(rt8); m_posRect = pOne->GetRect(); TRACE("Old_m_posRect:%lf,%lf,%lf,%lf,%lf,%lf\r\n" , m_posRect.left, m_posRect.top, m_posRect.right, m_posRect.bottom, m_posRect.Width(), m_posRect.Height()); m_posRect.SetRect(rt8.left, rt8.top, rt8.right, rt8.bottom); TRACE("New_m_posRect:%lf,%lf,%lf,%lf%lf,%lf\r\n" , m_posRect.left, m_posRect.top, m_posRect.right, m_posRect.bottom, m_posRect.Width(), m_posRect.Height()); LoadRectPath(path, m_posRect); } break; case DOUBLEFOX_XYZ: case DOUBLEFOX_POINT: if (m_bPointTextSelected) { CPointNameEx* ppn = (CPointNameEx*)pOne->GetValue(); CRect8 range(1e100, -1e100, -1e100, 1e100); ppn->GetRangeText(range, pOne->GetHowToViewPoint()); LoadRectPath(path, range); } else { m_posRect = pOne->GetRect(); LoadRectPath(path, m_posRect); } break; default: m_posRect = pOne->GetRect(); LoadRectPath(path, m_posRect); break; } //CClientDC dc(GetView()); m_Tracker.AddPath(path, bNeedRect); } void CItemSelect::LoadCurvePath(GraphicsPath& path, CCurveEx* pc) { if (pc == NULL) return; Gdiplus::Point *pt = new Gdiplus::Point[pc->num]; CPoint point; bool bPoint = true; for (int i = 0; i < pc->num; i++) { point = GetDC()->GetScreen(pc->x[i], pc->y[i]); if (i > 0) { if (point.x != pt[i - 1].X || point.y != pt[i - 1].Y) { bPoint = false; } } pt[i].X = point.x; pt[i].Y = point.y; } if (bPoint) { delete[] pt; pt = new Gdiplus::Point[5]; pt[0].X = point.x - 1; pt[0].Y = point.y - 1; pt[1].X = point.x - 1; pt[1].Y = point.y + 1; pt[2].X = point.x + 1; pt[2].Y = point.y + 1; pt[3].X = point.x + 1; pt[3].Y = point.y - 1; pt[4].X = point.x - 1; pt[4].Y = point.y - 1; path.AddCurve(pt, 5, 0); } else { path.AddCurve(pt, pc->num, 0); } //path.CloseFigure(); delete[] pt; } void CItemSelect::LoadRectPath(GraphicsPath& path, CRect8 rect) { CCurveEx* pCurve = new CCurveEx(5); pCurve->CreateCurveFromRect(&rect); LoadCurvePath(path, pCurve); delete pCurve; } void CItemSelect::SetSelectTypes(int* types, int size) { this->SelectTypes.clear(); for (int i = 0; i < size; i++) { this->SelectTypes.push_back(types[i]); } } // rect is in device coordinates void CItemSelect::SelectWithinRect(CRect8 rect, BOOL bAdd) { CPositionList select; GetDoc()->GetDraw()->IsInRange(rect,select); Select(select,bAdd); } void NItem::CItemSelect::SetEnableRotate(bool enable) { this->m_bEnableRotate = enable; } void CItemSelect::Select(CPositionList& select, BOOL bAdd) { if (!bAdd) { Select(NULL); //ClearAll(pDC); } CXy* pxy = GetDoc()->GetDraw(); POSITION pos,posObj; pos = select.GetHeadPosition(); while (pos != NULL) { posObj = select.GetNext(pos); if (this->SelectTypes.size() > 0) { if (std::find(SelectTypes.begin(), SelectTypes.end() , pxy->GetAt(posObj)->GetType()) == SelectTypes.end()) { continue; } } m_selection.AddTail(posObj); } GetDoc()->ReplaceSelectionSet(m_selection); ReloadTrackerPath(); } void CItemSelect::Deselect(POSITION posObj) { if(posObj==NULL) return; CRect rt= m_Tracker.GetInvalidateRect(); POSITION pos = m_selection.Find(posObj); if (pos != NULL) m_selection.RemoveAt(pos); //GetDoc()->CDrawDoc::Invalidate(&rt); //GetDoc()->Invalidate(&rt); //***要调用此函数。 SetPos(NULL); if(GetItemForGrid() && GetItemForGrid()->GetPos()==posObj) { GetItemForGrid()->InitializationMul(); GetItemForGrid()->SetPos(NULL); DeleteItemGrid(); //GetDoc()->UpdatePropertyGridContent(this); } } void CItemSelect::Remove(POSITION posObj) { POSITION pos = m_selection.Find(posObj); if (pos != NULL) m_selection.RemoveAt(pos); } BOOL CItemSelect::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { m_isLocationChanged = false; switch(nChar) { case VK_CONTROL: case VK_SPACE: break; case VK_ESCAPE: if( this->IsCaptureState() && selectMode==netSelect ) return CItemFocusRect::OnKeyDown(nChar,nRepCnt,nFlags); else Select(NULL); return TRUE; case VK_DELETE: int nResult = DeleteSelection(); return nResult; break; } BOOL brt=FALSE; CPoint2D ofd(0,0); if(GetCountSelected()>0) switch(nChar) { case VK_LEFT: ofd.x0=GetDC()->GetRealWidth(-1.0);//1个象素 brt=TRUE; break; case VK_RIGHT: ofd.x0=GetDC()->GetRealWidth(1.0); brt=TRUE; break; case VK_UP: ofd.y0=GetDC()->GetRealHeight(-1.0); brt=TRUE; break; case VK_DOWN: ofd.y0=GetDC()->GetRealHeight(1.0); brt=TRUE; break; default: brt=FALSE; break; } if(brt) { TRACE(_T("OnKeyDown:nRepCnt=%ld\n"), nRepCnt); OffsetSelected(ofd.x0, ofd.y0); } return brt; } BOOL CItemSelect::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) { switch(nChar) { case VK_CONTROL: case VK_SPACE: break; case VK_ESCAPE: CItemFocusRect::OnKeyUp(nChar, nRepCnt, nFlags); if(GetCountSelected()>0) { Select(NULL); return TRUE; } break; } return CItem::OnKeyUp(nChar, nRepCnt, nFlags); } void CItemSelect::InvalidateSelection(void) { if(m_selection.IsEmpty()) return; GetDoc()->InvalidateSelection(m_selection); } QTransformTracker& CItemSelect::GetTracker() { return m_Tracker; } void CItemSelect::EnableTracker(bool bEnbale) { m_bTrackerEnable = bEnbale; } //QTransformTracker* CItemSelect::GetQTracker() //{ // QTransformTracker* trc = &(GetDoc()->GetTracker()); // return trc; //} bool CItemSelect::InitItemForGrid() { if (m_selection.IsEmpty()) return false; if (GetCountSelected() != 1) return false; DeleteItemGrid(); POSITION pos = m_selection.GetHead(); m_pItemForGrid = FindItemForGrid(pos, FALSE); if (m_pItemForGrid) { m_pItemForGrid->SetPos(pos); //return m_pItemForGrid->InitPropertyGrid(grid); } return true; } void CItemSelect::CancelSelection(void) { Select(NULL); ReloadTrackerPath(); } BOOL CItemSelect::IsSelected(POSITION pos) { if(m_selection.Find(pos)) return TRUE; return FALSE; } CItem* CItemSelect::FindItemForGrid(POSITION pos, BOOL bMulElement) { if(pos==NULL) return NULL; CItem* pItem=NULL; COne* pOne=(COne*)GetDoc()->GetDraw()->GetAt(pos); if(!bMulElement) { pItem = GetDoc()->FindItem(pOne->GetType()); return pItem; switch(pOne->GetType()) { case DOUBLEFOX_PROPORTION: pItem=new CItemProportion(GetDoc()); break; //case DOUBLEFOX_IMAGE: pItem=new CItemFileImage(GetDoc()); break; //case DOUBLEFOX_MXN: pItem=new CItemFileMxn(GetDoc()); break; case DOUBLEFOX_ELLIPSE: pItem=new CItemEllipse(GetDoc()); break; case DOUBLEFOX_CIRCLE: pItem=new CItemCircle(GetDoc()); break; //case DOUBLEFOX_ARC: pItem=new CItemArc(GetDoc()); break; //case DOUBLEFOX_INSERT: pItem=new CItemInsertOld(GetDoc()); break; //case DOUBLEFOX_DRAW: pItem=new CItemInsertDraw(GetDoc()); break; case DOUBLEFOX_XYZ: case DOUBLEFOX_POINT: pItem=new CItemPointEdit(GetDoc()); break; //case DOUBLEFOX_XPOINT: pItem=new CItemXPointEdit(GetDoc()); break; //case DOUBLEFOX_FRAME: pItem=new CItemEditFrame(GetDoc()); break; case DOUBLEFOX_GRID: pItem=new CItemEditGrid(GetDoc()); break; //case DOUBLEFOX_NET: pItem=new CItemEditNet(GetDoc()); break; //case DOUBLEFOX_TEXT: pItem=new CItemText(GetDoc()); break; case DOUBLEFOX_MESH: pItem=new CItemMesh(GetDoc()); break; ////case DOUBLEFOX_DONUT: pItem=new CItemDonut(GetDoc()); break; //case DOUBLEFOX_CURVE: pItem=new CItemCurveEdit(GetDoc()); break; //case DOUBLEFOX_CURVE_STATION:pItem=new CItemCurveStation(GetDoc(), FALSE); break; //case DOUBLEFOX_TV: pItem=new CItemCurveTV(GetDoc(), FALSE);break; //case DOUBLEFOX_DRAW_RECT: pItem=new CItemMatrixMark(GetDoc()); break; //case DOUBLEFOX_SECTION: pItem=new CItemSection(GetDoc()); break; //case DOUBLEFOX_WMF: pItem=new CItemWMF(GetDoc()); break; //case DOUBLEFOX_OLE: pItem=new CItemOle(GetDoc()); break; //case DOUBLEFOX_SCALERULER: pItem=new CItemScaleRuler(GetDoc()); break; //case DOUBLEFOX_CRECT: pItem=new CItemRectangle(GetDoc()); break; case DOUBLEFOX_CROSSPOINT: pItem=new CItemPointCrossEdit(GetDoc());break; case DOUBLEFOX_TWOPOINT: pItem=new CItemPointTwoEdit(GetDoc()); break; //case DOUBLEFOX_PATHFILL: pItem=new CItemPathFill(GetDoc()); break; //case DOUBLEFOX_WELL: pItem=new CItemWell(GetDoc()); break; //case DOUBLEFOX_3D_FAULTSURFACE: //case DOUBLEFOX_BLOCK: pItem = new CItemBlock(GetDoc()); break; //case DOUBLEFOX_SCATTER: pItem = new CItemChart(GetDoc(),CCrossChart::scatter); break; //case DOUBLEFOX_OILWATER: pItem = new CItemChart(GetDoc(),CCrossChart::oilwater); break; //case DOUBLEFOX_HISTOGRAM: pItem = new CItemChart(GetDoc(),CCrossChart::histogram); break; //case DOUBLEFOX_RTPORLOG: pItem = new CItemChart(GetDoc(),CCrossChart::rtporlog); break; //case DOUBLEFOX_RWASP: pItem = new CItemChart(GetDoc(),CCrossChart::rwaspcross); break; //case DOUBLEFOX_CROSS: pItem = new CItemChart(GetDoc(),CCrossChart::cross); break; //case DOUBLEFOX_LIGASCROSS: pItem = new CItemChart(GetDoc(),CCrossChart::ligascross); break; //case DOUBLEFOX_WELLDATAGRAPH: pItem = new CItemWellDataGraph(GetDoc()); break; //case DOUBLEFOX_CHARTEX: pItem = new CItemChartEx(GetDoc()); break; //case DOUBLEFOX_RECTLABEL: pItem = new CItemLabelRect(GetDoc()); break; default: pItem = new CItem(GetDoc()); break; } } else { switch(pOne->GetType()) { //case DOUBLEFOX_CURVE: pItem=new CItemCurveEditMul(GetDoc()); break; //case DOUBLEFOX_DRAW: pItem=new CItemInsertDrawMul(GetDoc()); break; //case DOUBLEFOX_POINT: pItem=new CItemPointEdit(GetDoc()); break; case DOUBLEFOX_PROPORTION: pItem=new CItemProportion(GetDoc()); break; //case DOUBLEFOX_IMAGE: pItem=new CItemFileImage(GetDoc()); break; //case DOUBLEFOX_MXN: pItem=new CItemFileMxn(GetDoc()); break; //case DOUBLEFOX_ELLIPSE: pItem=new CItemEllipse(GetDoc()); break; //case DOUBLEFOX_CIRCLE: pItem=new CItemCircle(GetDoc()); break; //case DOUBLEFOX_ARC: pItem=new CItemArc(GetDoc()); break; //case DOUBLEFOX_XPOINT: pItem=new CItemXPointEdit(GetDoc()); break; //case DOUBLEFOX_FRAME: pItem=new CItemEditFrame(GetDoc()); break; case DOUBLEFOX_GRID: pItem=new CItemEditGrid(GetDoc()); break; //case DOUBLEFOX_NET: pItem=new CItemEditNet(GetDoc()); break; //case DOUBLEFOX_TEXT: pItem=new CItemText(GetDoc()); break; //case DOUBLEFOX_MESH: pItem=new CItemMesh(GetDoc()); break; //case DOUBLEFOX_CURVE_STATION:pItem=new CItemCurveStation(GetDoc()); break; //case DOUBLEFOX_TV: pItem=new CItemCurveTV(GetDoc()); break; //case DOUBLEFOX_DRAW_RECT: pItem=new CItemMatrixMark(GetDoc()); break; //case DOUBLEFOX_SECTION: pItem=new CItemSection(GetDoc()); break; //case DOUBLEFOX_WMF: pItem=new CItemWMF(GetDoc()); break; //case DOUBLEFOX_OLE: pItem=new CItemOle(GetDoc()); break; default: pItem=new CItem(GetDoc()); break; } } return pItem; } /* BOOL CItemSelect::InitPropertyGrid(CXTPPropertyGrid& grid) { if(m_selection.IsEmpty()) return FALSE; if(GetCountSelected()==1) { DeleteItemGrid(); POSITION pos=m_selection.GetHead(); m_pItemForGrid=FindItemForGrid(pos, FALSE); if(m_pItemForGrid) { m_pItemForGrid->SetPos(pos); return m_pItemForGrid->InitPropertyGrid(grid); } } else if(IsSameType()) { DeleteItemGrid(); POSITION pos=m_selection.GetHead(); m_pItemForGrid=FindItemForGrid(pos, TRUE); if(m_pItemForGrid) { return m_pItemForGrid->InitPropertyGridMul(grid); } } return TRUE; } */ /* BOOL CItemSelect::OnGridItemChangeValue(CXTPPropertyGridItem* pItem) { if(pItem==NULL) return FALSE; if(GetItemForGrid()==NULL) return FALSE; GetDoc()->BeginWaitCursor(); BOOL rn=FALSE; if(GetCountSelected()==1) rn=GetItemForGrid()->OnGridItemChangeValue(pItem); else rn=GetItemForGrid()->OnGridItemChangeValueMul(pItem); if(rn) { CRect rt=GetDoc()->GetTracker().GetInvalidateRect(); GetDoc()->CDrawDoc::Invalidate(&rt); ReloadTrackerPath(); } return rn; } */ void CItemSelect::DeleteItemGrid(void) { if(m_pItemForGrid) delete m_pItemForGrid; m_pItemForGrid=NULL; } void CItemSelect::GetSelectedNames(CString& names) { names.Empty(); COne* pOne; POSITION pos, pt; pos = m_selection.GetHeadPosition(); while (pos != NULL) { pt = m_selection.GetNext(pos); pOne = (COne*)GetDoc()->GetDraw()->GetAt(pt); names += (pOne->GetName() + ","); } } void CItemSelect::Copy(void) { //GetDoc()->BeginWaitCursor(); // Create a shared file and associate a CArchive with it CSharedFile file; CArchive ar(&file, CArchive::store); // Serialize selected objects to the archive Serialize(GetDoc()->GetDraw(), m_selection, ar, false); AfxGetPublicFunction()->WriteElementType(ar,0,CUR_VERSION); //写文件结束标志 ar.Close(); COleDataSource* pDataSource = NULL; TRY { pDataSource = new COleDataSource; // put on local format instead of or in addation to pDataSource->CacheGlobalData(CSigmaView::m_clipboardDraw, file.Detach()); pDataSource->SetClipboard(); } CATCH_ALL(e) { delete pDataSource; THROW_LAST(); } END_CATCH_ALL } //fbw //0=粘贴到当前文件,1=粘贴到当前层,2=粘贴为符号, 3=粘贴为块 bool CItemSelect::Past(int nPasteMode) { //GetDoc()->BeginWaitCursor(); // invalidate current selection since it will be deselected Select(NULL); CXy* pxy = NULL; bool bDeleteXy = false; switch(nPasteMode) { case 0: //粘贴到当前文件 case 1: //粘贴到当前层 pxy = GetDoc()->GetDraw(); break; case 2: //粘贴为符号 case 3: //粘贴为块 pxy = new CXy; bDeleteXy = true; break; } if(pxy==NULL) return false; bool bPasteAsMark = nPasteMode==2 ? true:false; bool bPasteAsBlock = nPasteMode==3 ? true:false; if(bPasteAsMark) //粘贴为符号 { //fbw //CItemOther item(NULL); //item.SetIdea(OTHER_MARK_NAME); //item.name = "NewMark"; //CPropertiesSheet sheet(ID_EDIT_PASTE_AS_MARK, GetView(), 0, FALSE); //sheet.SetItem(&item); //if(sheet.DoModal()!=IDOK) return; //int rt=CDFDrawProDoc::TryToAddMark(pxy, item.name, NULL, GetView()); //if(rt <= 0) //取消或放弃 // return; //pxy->m_strName = item.name; } COleDataObject dataObject; dataObject.AttachClipboard(); BOOL bIsDraw = dataObject.IsDataAvailable(CSigmaView::m_clipboardDraw); if (bIsDraw) { bool bPasteInCurrentLayer = nPasteMode==1 ? true:false; PasteNative(pxy, m_selection, dataObject, bPasteInCurrentLayer); } else { CRect rect; rect = GetView()->GetClientRect(); rect.DeflateRect(rect.Width()/4, rect.Height()/4); CRect8 rt=GetDC()->GetReal(rect); rt.NormalizeRect(); CClipboard cb; BOOL bIsText = cb.IsText(); CString text; if(bIsText) bIsText = cb.GetText(text); if(bIsText) { CText *pText=new CText; pText->x0=rt.left; pText->y0=rt.top; pText->m_size.cy=fabs(GetDC()->GetRealHeight((long)15)); pText->m_size.cx=pText->m_size.cy*0.4; pText->SetName(text); POSITION pos = pxy->AddElement(pText, DOUBLEFOX_TEXT); if (pos) { m_selection.AddTail(pos); GetDoc()->ReplaceSelectionSet(m_selection); } } else { //元文件时 CMetaFile* pMeta=new CMetaFile; if(pMeta->PastFromClipboard()) { CSize sz=pMeta->GetWmfSize(); CSize8 size=rt.GetSize(); CSize8 offSize; pMeta->m_size.SetSize(sz.cx, sz.cy); AfxGetPublicFunction()->GetScaleSize(size, pMeta->m_size, offSize); pMeta->x0 = rt.left +offSize.cx; pMeta->y0 = rt.bottom+offSize.cy; POSITION pos = pxy->AddElement(pMeta, DOUBLEFOX_WMF); if (pos) { m_selection.AddTail(pos); GetDoc()->ReplaceSelectionSet(m_selection); } } else { delete pMeta; //图像文件 CImageInsert * pImage=new CImageInsert; if(pImage->PastFromClipboard()) { CSize8 size=rt.GetSize(); CSize8 offSize; pImage->m_size.SetSize(pImage->m_pImage->GetWidth(), pImage->m_pImage->GetHeight()); AfxGetPublicFunction()->GetScaleSize(size, pImage->m_size, offSize); pImage->x0 = rt.left +offSize.cx; pImage->y0 = rt.bottom+offSize.cy; POSITION pos = pxy->AddElement(pImage, DOUBLEFOX_IMAGE); if (pos) { m_selection.AddTail(pos); GetDoc()->ReplaceSelectionSet(m_selection); } } else { delete pImage; //其它的OLE对象 POSITION pos = PasteEmbedded(pxy, dataObject, CPoint(0,0)); if (pos) { m_selection.AddTail(pos); GetDoc()->ReplaceSelectionSet(m_selection); } } } } } if(m_selection.IsEmpty()) { if(bDeleteXy) delete pxy; return false; } else if(bPasteAsMark) { m_selection.RemoveAll(); if(GetDoc()->GetDraw()->AddMark(pxy)) { //插入一个符号元素 CSigmaView* pView = GetView(); CRect rt; rt = pView->GetClientRect(); CRect8 rect = GetDC()->GetReal(rt); rect.DeflateRect(rect.Width()*0.25, rect.Height()*0.25); CInsertDraw* pInsert=new CInsertDraw; pInsert->SetName(pxy->m_strName); pInsert->x0=rect.left; pInsert->y0=rect.bottom; pInsert->pDraw=pxy; pInsert->rect=pxy->m_range; if(fabs(pInsert->rect.Height())>fabs(pInsert->rect.Width())) { pInsert->m_size.cy=fabs(rect.Height()); pInsert->m_size.cx=fabs(pInsert->rect.Width()/pInsert->rect.Height()*rect.Height()); pInsert->x0+=(fabs(rect.Height())-pInsert->m_size.cx)*0.5; } else { pInsert->m_size.cy=fabs(pInsert->rect.Height()/pInsert->rect.Width()*rect.Width()); pInsert->m_size.cx=fabs(rect.Width()); pInsert->y0+=(rect.Width()-pInsert->m_size.cy)*0.5; } POSITION pos = GetDoc()->GetDraw()->AddElement(pInsert,DOUBLEFOX_DRAW); m_selection.AddTail(pos); GetDoc()->ReplaceSelectionSet(m_selection); } else { delete pxy; return false; } } else if(bPasteAsBlock) { m_selection.RemoveAll(); CInsertBlock* pb = new CInsertBlock; pb->SetXy(pxy); POSITION pos = GetDoc()->GetDraw()->AddElement(pb,DOUBLEFOX_BLOCK); m_selection.AddTail(pos); GetDoc()->ReplaceSelectionSet(m_selection); } UINT nId; switch(nPasteMode) { default: case 0: nId = IDS_STRING_PASTE; break; case 1: nId = ID_EDIT_PASTE_IN_CURRENT_LAYER; break; case 2: nId = ID_EDIT_PASTE_AS_MARK; break; case 3: nId = ID_EDIT_PASTE_BLOCK; break; } //做Undo操作 if(bPasteAsMark) { //增加符号 CActionListItem* pAction = new CActionListItem(GetDoc(), nId); //pAction->AddMarkAddItem(pxy); pAction->AddAddItem(m_selection); GetDoc()->SetActionItem(pAction); } else GetDoc()->SetActionItem(new CActionAddItem(GetDoc(), nId, m_selection)); //刷新增加的元素 ReloadTrackerPath(); GetDoc()->Modified(); return true; //CMainFrame* pmf = (CMainFrame*)GetDoc()->GetMainFrame(); //if(bIsDraw && pmf) //{ // pmf->LoadLayer(GetDoc()->GetDraw()); // pmf->EagleEyeUpdate(GetDoc()->GetDraw()); //} //GetView()->SetFocus(); //将焦点设置到客户区 } BOOL CItemSelect::IsCanPaste(void) { return TRUE; /* // determine if private or standard OLE formats are on the clipboard CClipboard cb; BOOL bText=cb.IsText(); COleDataObject dataObject; BOOL bEnable = dataObject.AttachClipboard() && (dataObject.IsDataAvailable(CDFDrawProView::m_clipboardDraw) || COleClientItem::CanCreateFromData(&dataObject) || bText==TRUE ); return bEnable; */ } //fbw void CItemSelect::PasteNative(CXy* pDraw, CPositionList& list, COleDataObject& dataObject, bool bPasteInCurrentLayer) { //bPasteInCurrentLayer = true; //sjc // get file refering to clipboard data CFile* pFile = dataObject.GetFileData(CSigmaView::m_clipboardDraw); if(pFile == NULL) return; // connect the file to the archive CArchive ar(pFile, CArchive::load); TRY { //ar.m_pDocument = GetDoc(); // set back-pointer in archive // read the selection Serialize(pDraw, list, ar, bPasteInCurrentLayer); } CATCH_ALL(e) { ar.Close(); delete pFile; THROW_LAST(); } END_CATCH_ALL ar.Close(); delete pFile; } //fbw void CItemSelect::Serialize(CXy* pDraw, CPositionList& list, CArchive& ar, bool bPasteInCurrentLayer) { CLayer* pCurLayer = pDraw->GetCurrentLayer(); CXy* pxy = NULL; if(ar.IsLoading()) { if(bPasteInCurrentLayer) { pxy = new CXy; } } if(pxy) GetDoc()->Serialize(ar, list, pxy); else GetDoc()->Serialize(ar, list, pDraw); if(!ar.IsLoading()) return; //////////////////////////////////////////////////////////////////////// //粘贴到当前层时 //重新定位符号 AfxGetGlobalMark()->BackupMark(); AfxGetGlobalMark()->SetMark(pDraw->GetMark()); //增加并设置到当前层 if(pxy) { pxy->SetCurrentLayer(pCurLayer->GetPathName()); CLayer* pxyCurLayer = pxy->GetCurrentLayer(); POSITION pos; POSITION pt = list.GetHeadPosition(); while(pt) { pos = list.GetNext(pt); pxy->SetElementLayer(pos, pxyCurLayer); } pxy->ClearNoUseMark(); pxy->ClearLayerNoneData(); list.RemoveAll(); pDraw->MoveIn(pxy, list); delete pxy; } pDraw->SetCurrentLayer(pCurLayer); AfxGetGlobalMark()->RestoreMark(); } bool CItemSelect::WriteData(CXy* pDraw, BYTE*& outBuffer, int& destLen, int formatCode) { //m_selection return pDraw->WriteMemory(outBuffer, destLen,m_selection, formatCode, 0); } POSITION CItemSelect::PasteEmbedded(CXy* pDraw, COleDataObject& dataObject, CPoint point ) { return 0; /* GetView()->BeginWaitCursor(); CRect rt; GetView()->GetClientRect(&rt); rt.DeflateRect(rt.Width()/4, rt.Height()/4); // paste embedded COleObjectEx* pObj = new COleObjectEx(); pObj->SetRect(GetDC()->GetReal(rt)); CDFDrawProCntrItem* pItem = new CDFDrawProCntrItem(GetDoc(), pObj); ASSERT_VALID(pItem); pObj->SetOleItem(pItem); POSITION pos = NULL; TRY { if (!pItem->CreateFromData(&dataObject) && !pItem->CreateStaticFromData(&dataObject)) { AfxThrowMemoryException(); // any exception will do } // try to get initial presentation data pItem->UpdateLink(); // add the object to the document pos = pDraw->AddElement(pObj, DOUBLEFOX_OLE); //Select(pos); ////for undo/redo //GetDoc()->SetActionItem(new CActionAddItem(GetDoc(), IDS_STRING_PASTE, m_selection)); } CATCH_ALL(e) { // clean up item if(pObj) delete pObj; AfxMessageBox(IDP_FAILED_TO_CREATE); } END_CATCH_ALL GetView()->EndWaitCursor(); return pos; */ } CItem* CItemSelect::GetItemForGrid(void) { return m_pItemForGrid; } int CItemSelect::GetCountSelected(void) { return (int)m_selection.GetCount(); } void CItemSelect::OffsetSelected(double dx, double dy) { BOOL bIsPointText=FALSE; if(m_selection.GetCount()==1) { //为了能直接移动点的文本项 POSITION pos=m_selection.GetHead(); COne* pOne=(COne*)GetDoc()->GetDraw()->GetAt(pos); if( (pOne->GetType()==DOUBLEFOX_POINT||pOne->GetType() == DOUBLEFOX_XYZ) && m_bPointTextSelected==TRUE) { bIsPointText=TRUE; //GetDoc()->SetActionItem(new CActionBackupItem(GetDoc(),IDS_STRING_ACTION_MOVE,m_selection)); if(pOne->HowToViewPoint==NULL) { pOne->HowToViewPoint=new CHowToViewPoint; if(pOne->GetLayer()->HowToViewPoint) //层修饰 *(pOne->HowToViewPoint)=*(pOne->GetLayer()->HowToViewPoint); } pOne->HowToViewPoint->m_delt.cx+=dx; pOne->HowToViewPoint->m_delt.cy+=dy; } } if(!bIsPointText) { COne* pOne; POSITION pos,pt; pos = m_selection.GetHeadPosition(); while (pos != NULL) { pt = m_selection.GetNext(pos); pOne=(COne*)GetDoc()->GetDraw()->GetAt(pt); pOne->Offset(dx,dy); } m_isLocationChanged = true; //for redo/undo CPoint2D point(dx, dy); CActionOffsetItem *pAction=new CActionOffsetItem(GetDoc(), IDS_STRING_ACTION_MOVE, m_selection, point); GetDoc()->SetActionItem(pAction); } ReloadTrackerPath(); //GetDoc()->Modified(); //***MFC函数,要替换此函数。 } CRect8 CItemSelect::GetSelectedRect(void) { CRect8 rect(0,0,0,0); if(GetCountSelected()>0) { COne* pOne; rect.SetRect(1e100,-1e100,-1e100,1e100); POSITION pos,pt; pos = m_selection.GetHeadPosition(); while (pos != NULL) { pt = m_selection.GetNext(pos); pOne=(COne*)GetDoc()->GetDraw()->GetAt(pt); pOne->GetRange(rect); } } return rect; } void CItemSelect::SelectSameLayer(void) { if(GetCountSelected()==0) return; //获得选择元素的层名 int i; CStringArray arrLayer; BOOL bFind; CString txt; POSITION pos, pt; pos=m_selection.GetHeadPosition(); while(pos) { pt=m_selection.GetNext(pos); txt=GetDoc()->GetDraw()->GetElementLayer(pt)->GetPathName(); bFind=FALSE; for(i=0;iGetDraw()->GetElement(arrLayer[i],list); } Select(list); GetDoc()->Invalidate(); } void CItemSelect::SelectSameProperty(void) { if(GetCountSelected()==0) return; //获得选择元素的类型 int i, type; CArray arrType; BOOL bFind; POSITION pos, pt; pos=m_selection.GetHeadPosition(); while(pos) { pt=m_selection.GetNext(pos); type=GetDoc()->GetDraw()->GetElementType(pt); bFind=FALSE; for(i=0;iGetDraw()->GetElement(arrType[i],list); } Select(list); GetDoc()->Invalidate(); } BOOL CItemSelect::IsSameType(void) { if(m_selection.IsEmpty()) return FALSE; int type=0; POSITION pos,pt; pos=m_selection.GetHeadPosition(); if(pos) { pt=m_selection.GetNext(pos); type=GetDoc()->GetDraw()->GetElementType(pt); } while(pos) { pt=m_selection.GetNext(pos); if(type!=GetDoc()->GetDraw()->GetElementType(pt)) return FALSE; } return TRUE; } BOOL CItemSelect::IsElementType(int nElementType) { if(m_selection.IsEmpty()) return FALSE; POSITION pos,pt; pos=m_selection.GetHeadPosition(); while(pos) { pt=m_selection.GetNext(pos); if(nElementType != GetDoc()->GetDraw()->GetElementType(pt)) return FALSE; } return TRUE; } BOOL NItem::CItemSelect::IsCanMoveCoor(COne* pOne) { BOOL bMoveCoor=TRUE; if(pOne->HowToViewPoint!=NULL) { if(!pOne->HowToViewPoint->IsCanMoveCoordinate()) bMoveCoor=FALSE; } else if(pOne->GetLayer()->HowToViewPoint!=NULL) { if(!pOne->GetLayer()->HowToViewPoint->IsCanMoveCoordinate()) bMoveCoor=FALSE; } return bMoveCoor; } POSITION NItem::CItemSelect::SelectionToFillPath(void) { CSigmaDoc * pDoc = GetDoc(); CXy* pNewXy=SelectionToXy(); if(pNewXy==NULL) return NULL; CPathFill *pp=new CPathFill; pp->SetXy(pNewXy); pp->Draw(GetDC()); POSITION pos = GetDoc()->GetDraw()->AddElement(pp, DOUBLEFOX_PATHFILL); //for undo/redo //CActionListItem* pAction=new CActionListItem(GetDoc(), ID_EDIT_GROUP_FILLPATH); //插入符号元素 COne* pOne = GetDoc()->GetDraw()->GetAt(pos); //pAction->AddAddItem(pOne); //为了恢复元素 //pAction->AddDeleteItem(m_selection); //GetDoc()->SetActionItem(pAction); Select(pos); ReloadTrackerPath(); return pos; } int NItem::CItemSelect::DisperseMetaEmf(POSITION pos, CXy* pXy, long timestamp) { if (pos == NULL) return 0; COne* pOne; pOne = (COne*)GetDoc()->GetDraw()->GetAt(pos); if (pOne->GetType() == DOUBLEFOX_WMF) { CMetaFile* meta = (CMetaFile*)pOne->GetValue(); CString filePath = meta->GetName(); CSplitPath sp; if (filePath.IsEmpty()) { sp.SetModuleFileName(); filePath.Format("%s%s", sp.GetPath(), "emfpath"); sp.MakeDirectory(filePath); filePath = sp.GetAbsolutePath(filePath); CString metaFileName = CString(std::to_string(timestamp).c_str()) + CString(".emf"); filePath = filePath + "\\" + metaFileName; if (!meta->SaveMetaFile(filePath)) { return 0; } } filePath = sp.GetAbsolutePath(filePath); CXy* pXyEmf = new CXy; if (!pXyEmf->FromEmf(filePath)) { delete pXyEmf; return 0; } CRect8 range = pXy->GetRange(); CXyBlock* pXyBlock = new CXyBlock; pXyBlock->SetXy(pXyEmf); CRect8 range1; range1.SetRect(1e100, -1e100, -1e100, 1e100); pXyBlock->GetRange(range1); double dx = std::abs(range.right - range.left); double dy = std::abs(range.bottom - range.top); double dx1 = std::abs(range1.right - range1.left); double dy1 = std::abs(range1.bottom - range1.top); double scale_dx = (dx * 1) / dx1; double scale_dy = (dy * 1) / dy1; pXyBlock->Offset(range.left, range.top); pXyBlock->ScaleProperty(scale_dx, scale_dy); pXyBlock->ScaleCoor(range.left, range.top, scale_dx, scale_dy); pXy->AddElement(pXyBlock, DOUBLEFOX_BLOCK); //删除之前的MetaFile DeleteSelection(); //if(fileState) remove(filePath); } return 1; } CXy* CItemSelect::SelectionToXy() { CSigmaDoc * pDoc = GetDoc(); CList* ps=&m_selection; if(ps->IsEmpty()) return NULL; CLayerList* pClass; CXy* pNewXy=new CXy; COne* pOne,*pNewOne; CLayer* pLayer; //增加组合元素到新的符号中 POSITION p,pos; p=ps->GetHeadPosition(); while(p) { pos=ps->GetNext(p); pOne=(COne*)GetDoc()->GetDraw()->GetAt(pos); pClass=pNewXy->GetClass(pOne->GetLayer()->GetClassName()); if(pClass==NULL) pClass=pNewXy->AddClass(pOne->GetLayer()->GetClassName()); pLayer=pNewXy->FindLayer(pOne->GetLayer()->GetPathName()); if(pLayer==NULL) { pLayer=new CLayer; *pLayer=*pOne->GetLayer(); pLayer->SetParentClass(pClass); pNewXy->SetCurrentLayer(pLayer); } pNewOne=new COne; *pNewOne=*pOne; if(pLayer) pNewOne->SetLayer(pLayer); pNewXy->AddTailOne(pNewOne); } //将其使用到的符号复制到该符号中 CStringList markList; CString markName; CXy* pFindMark; pNewXy->GetNewUsing(markList); p=markList.GetHeadPosition(); while(p) { markName=markList.GetNext(p); //插入新的符号 pFindMark=(CXy*)GetDoc()->GetDraw()->FindMark(markName); if(pFindMark) { CXy* pNewMark=new CXy; *pNewMark=*pFindMark; pNewXy->AddMark(pNewMark); } } pNewXy->PositionNew(0); return pNewXy; } bool NItem::CItemSelect::COneVisibleAndEditable(COne *pOne) { return pOne->IsView() && !pOne->GetLayer()->IsNotViewNotEdit(); } std::list NItem::CItemSelect::CollectLayerPolyline(CString layer) { std::list result; CXy* pXy = GetDoc()->GetDraw(); CXyElementFilter filter; filter.addLayer(layer, false) .addType(DOUBLEFOX_CURVE); NBase::CPositionList select; pXy->GetElement(m_selection, filter, select); for (POSITION pos = (select).GetHeadPosition(); pos != nullptr; (select).GetNext(pos)) { POSITION onePos = select.GetAt(pos); COne* pOne = pXy->GetAt(onePos); CCurveEx* pCurve = (CCurveEx*)(pOne->GetValue()); result.push_back(CurveExToPolyline(pCurve)); } return result; } std::list NItem::CItemSelect::CollectFlts(CCurveEx *pBlock) { std::list result; CXy* pXy = GetDoc()->GetDraw(); CString faultLayer = pXy->GetFaultLayer(); if (faultLayer.IsEmpty()) { return result; } CPositionList select; CXyElementFilter filter; filter.addLayer(faultLayer, true) .addType(DOUBLEFOX_CURVE); pXy->GetElement(filter, select); for (POSITION pos = (select).GetHeadPosition(); pos != nullptr; (select).GetNext(pos)) { POSITION onePos = select.GetAt(pos); COne *pOne = pXy->GetAt(onePos); CCurveEx* pCurve = (CCurveEx*)(pOne->GetValue()); int inside = pBlock->IsInside(*pCurve); if (inside == 0) { continue; } else if (inside == -1) { } if (IsEqual(pCurve, pBlock)) { continue; } //result.push_back(CurveExToPolyline(pCurve)); result.push_back(pCurve); } return result; } std::vector NItem::CItemSelect::CollectWells(CCurveEx *pBlock) { std::vector result; CXy* pXy = GetDoc()->GetDraw(); CPositionList select; CPositionList points; CPositionList xyzs; pXy->GetElement(DOUBLEFOX_POINT, points); pXy->GetElement(DOUBLEFOX_XYZ, xyzs); CListAddRange(select, points); CListAddRange(select, xyzs); for (POSITION pos = (select).GetHeadPosition(); pos != nullptr; (select).GetNext(pos)) { POSITION onePos = select.GetAt(pos); COne* pOne = pXy->GetAt(onePos); CPointNameBase *pPoint = (CPointNameBase *)pOne->GetValue(); if (pBlock->IsInside(pPoint->x0, pPoint->y0)) { CWellPoint well; well.x0 = pPoint->x0; well.y0 = pPoint->y0; well.z0 = pPoint->z0; well.SetName(pPoint->GetName()); result.push_back(well); } } return result; } int NItem::CItemSelect::PointCount() { CXy* pXy = GetDoc()->GetDraw(); int count = 0; std::vector polygons = CollectPolygons(); if (!polygons.empty()) { std::vector points = GetPointsInCurves(polygons); DeleteAll(polygons); return (int)points.size(); } for (POSITION pos = (m_selection).GetHeadPosition(); pos != nullptr; (m_selection).GetNext(pos)) { POSITION onePos = m_selection.GetAt(pos); COne *pOne = (COne *)pXy->GetAt(onePos); if (!COneVisibleAndEditable(pOne)) { continue; } int type = pOne->GetType(); if (type == DOUBLEFOX_POINT || type == DOUBLEFOX_XYZ) { count++; } } DeleteAll(polygons); return count; } POSITION NItem::CItemSelect::FirstPositionAfterWell() { CXy* pXy = GetDoc()->m_pXy; bool hasFindWell = false; POSITION posFirst = nullptr; CPtrList* pLst = pXy->GetValueList(); for (POSITION pos = (*pLst).GetHeadPosition(); pos != nullptr; (*pLst).GetNext(pos)) { COne* pOne = (COne *)(pLst->GetAt(pos)); if (!pOne->IsView()) { continue; } if (pOne->GetLayer()->IsNotViewNotEdit()) { continue; } if (pOne->GetType() == DOUBLEFOX_POINT || pOne->GetType() == DOUBLEFOX_XYZ) { hasFindWell = true; posFirst = pos; break; } //else if (hasFindWell) //{ // posFirst = pos; //} } if (posFirst == nullptr) { posFirst = pLst->GetHeadPosition(); } return posFirst; } void NItem::CItemSelect::DrawResultToLayer(CString layerName, std::list& result, CPositionList& addCurveList) { // 添加结果到图形 CXy* pXy = GetDoc()->m_pXy; CLayer *pLayer = pXy->FindAddLayer(layerName); POSITION posFirst = FirstPositionAfterWell(); COLORREF clr; srand(GetTickCount()); POSITION pt; for (auto &polyLine : result) { int iCount = polyLine.GetSize(); // 将 CPolyline 折线 转换为 自定义的折线类 CCurveEx* pCurve = PolylineToCurveEx(polyLine); clr = RGB(rand() % 210+30, rand() % 210+30, rand() % 210+30); CHowToViewCurve *pHowToViewCurve = new CHowToViewCurve(); CCurveProperties *pCurveView = new CCurveProperties(); pHowToViewCurve->Add(pCurveView); pCurveView = new CCurveProperties(); pCurveView->color = clr; pCurveView->SetCurveType(PLINE_SOLID); pHowToViewCurve->Add(pCurveView); pXy->SetCurrentLayer(pLayer); // 这个是为了保证图元显示顺序,防止生成的三角网、龟背图跑到背景下面去了 pt = pXy->InsertElementBefore(posFirst, pCurve, DOUBLEFOX_CURVE); COne *pOne = pXy->GetAt(pt); pOne->CopySetHowToViewCurve(pHowToViewCurve); delete pHowToViewCurve; addCurveList.AddTail(pt); } } int NItem::CItemSelect::DrawDelaunay(std::list& flts, std::vector& wells, CPolyline & border, std::list* results) { std::vector pts; pts.assign(wells.begin(), wells.end()); int num = border.GetSize(); for (int i = 0; i < num; i++) { double dX = border.GetPoint(i).x0; double dY = border.GetPoint(i).y0; bool find = std::any_of(pts.begin(), pts.end(), [dX, dY](const CWellPoint&pt) { return pt.x0 == dX && pt.y0 == dY; }); if (find == true) { continue; } CWellPoint well; well.x0 = dX; well.y0 = dY; well.z0 = border.GetPoint(i).z0; well.SetName(""); pts.push_back(well); } auto voronoiMap = std::make_unique(); voronoiMap->SetFltClosingFraction(0.1); voronoiMap->ReadWellData(pts); voronoiMap->CreateMap(flts, border); return voronoiMap->OutputTriangleLines(*results); } int NItem::CItemSelect::DrawVorono(std::list& flts, std::vector& wells, CPolyline & border, std::list* results) { auto voronoiMap = std::make_unique(); voronoiMap->SetFltClosingFraction(0.1); voronoiMap->ReadWellData(wells); voronoiMap->CreateMap(flts, border); for (auto it=flts.begin(); it != flts.end(); it++) { TRACE("Pline\n"); for (int i = 0; i < it->GetSize(); i++) { CPointXYZ pt = it->GetPoint(i); TRACE("%lf,%lf\n", pt.x0, pt.y0); } TRACE("\n"); } return voronoiMap->OutputResult(*results); } static bool CWellsContains(std::vector &wells, CWellPoint &point) { for (auto &well: wells) { if (well.x0 == point.x0&& well.y0 == point.y0 && well.z0 == point.z0) { return true; } } return false; } std::vector NItem::CItemSelect::GetWellByDelaunay(std::list& flts) { std::vector wells; for (auto &&flt : flts) { for (int i = 0; i < flt.GetSize(); i++) { CPointXYZ &point = flt.GetPoint(i); CWellPoint well; well.x0 = point.x0; well.y0 = point.y0; well.z0 = point.z0; well.SetName(point.GetName()); if (!CWellsContains(wells, well)) { wells.push_back(well); } } } return wells; } std::list NItem::CItemSelect::PositionsToCones(CPositionList &list) { std::list result; for (POSITION pos = (list).GetHeadPosition(); pos != nullptr; (list).GetNext(pos)) { POSITION pt = list.GetAt(pos); result.push_back(GetDoc()->GetDraw()->GetAt(pt)); } return result; } std::list NItem::CItemSelect::SelectionCones() { return PositionsToCones(m_selection); } std::vector NItem::CItemSelect::SelectedPointXYZs() { std::list points = SelectionCones(); std::vector result; CXy* pXy = GetDoc()->m_pXy; for (COne *pOne : points) { if (!COneVisibleAndEditable(pOne)) { continue; } if (pOne->GetType() == DOUBLEFOX_POINT || pOne->GetType() == DOUBLEFOX_XYZ) { CPointNameEx* ppn = (CPointNameEx*)pOne->GetValue(); result.push_back(CPointNameExToCPointXYZ(*ppn)); } } return result; } std::vector NItem::CItemSelect::GetPointsInCurves(std::vector& curves) { std::vector result; CXy* pXy = GetDoc()->m_pXy; if (curves.empty()) { return result; } NBase::CPositionList positions; pXy->GetElement(DOUBLEFOX_POINT, positions, FALSE); pXy->GetElement(DOUBLEFOX_XYZ, positions, FALSE); for (POSITION pos = (positions).GetHeadPosition(); pos != nullptr; (positions).GetNext(pos)) { POSITION pt = positions.GetAt(pos); COne* pOne = pXy->GetAt(pt); if (pOne->GetType() != DOUBLEFOX_POINT && pOne->GetType() != DOUBLEFOX_XYZ) { continue; } CPointNameEx* ppn = (CPointNameEx*)pOne->GetValue(); CPointXYZ pointXYZ = CPointNameExToCPointXYZ(*ppn); bool inCurves = AnyOf(curves, [&pointXYZ](CCurveEx* pCurve) { return pCurve->IsInside(pointXYZ.x0, pointXYZ.y0); }); if (inCurves) { CPointNameEx* ppn = (CPointNameEx*)pOne->GetValue(); result.push_back(CPointNameExToCPointXYZ(*ppn)); } } return result; } std::vector NItem::CItemSelect::CollectPolygons() { std::vector result; CXy* pXy = GetDoc()->GetDraw(); for (POSITION pos = (m_selection).GetHeadPosition(); pos != nullptr; (m_selection).GetNext(pos)) { POSITION pt = m_selection.GetAt(pos); COne* pOne = pXy->GetAt(pt); if (pOne->GetType() != DOUBLEFOX_CURVE) { continue; } if (!COneVisibleAndEditable(pOne)) { continue; } CCurveEx* pCurve = (CCurveEx*)pOne->GetValue(); if (IsApproximatePolygon(pCurve)) { CCurveEx* pNewCurve = CreateCloseCurve(pCurve); result.push_back(pNewCurve); } } return result; } POSITION CItemSelect::GroupSelectionToBlock() { CSigmaDoc * pDoc = GetDoc(); CList* ps=&m_selection; if(ps->IsEmpty()) return NULL; CXy* pNewXy=SelectionToXy(); if(pNewXy==NULL) return NULL; long count = 0; if (GetDoc()->GetDraw()->GetMark() != nullptr) { count = (int)GetDoc()->GetDraw()->GetMark()->GetCount(); } pNewXy->m_strName.Format("__GROUP__%ld",count); while(GetDoc()->GetDraw()->FindElement(pNewXy->m_strName)) pNewXy->m_strName.Format("__GROUP__%ld",++count); CInsertBlock* pblock = new CInsertBlock; pblock->SetXy(pNewXy); POSITION pos = AddElement(pblock, DOUBLEFOX_BLOCK, FALSE, FALSE); //for undo/redo CActionListItem* pAction=new CActionListItem(GetDoc(), ID_EDIT_GROUP); //插入符号元素 COne* pOne=GetDoc()->GetDraw()->GetAt(pos); pAction->AddAddItem(pOne); //为了恢复元素 pAction->AddDeleteItem(m_selection); GetDoc()->SetActionItem(pAction); Select(pos); ReloadTrackerPath(); return pos; } POSITION CItemSelect::GroupSelectionToSymbol() { CSigmaDoc * pDoc = GetDoc(); CList* ps=&m_selection; if(ps->IsEmpty()) return NULL; CXy* pNewXy=SelectionToXy(); if(pNewXy==NULL) return NULL; long count=(int)GetDoc()->GetDraw()->GetMark()->GetCount(); pNewXy->m_strName.Format("__GROUP__%ld",count); while(GetDoc()->GetDraw()->FindMark(pNewXy->m_strName))//有这个符号则更名 pNewXy->m_strName.Format("__GROUP__%ld",++count); GetDoc()->GetDraw()->AddMark(pNewXy); CRect8 rt=pNewXy->m_range; pNewXy->Offset(-rt.left,-rt.bottom); CInsertDraw* pInsert=new CInsertDraw; pInsert->SetName(pNewXy->m_strName); pInsert->pDraw=pNewXy; pInsert->x0=rt.left; pInsert->y0=rt.bottom; pInsert->m_size.cx=rt.Width(); pInsert->m_size.cy=fabs(rt.Height()); pInsert->rect=rt; pInsert->rect.OffsetRect(-rt.left,-rt.bottom); POSITION pos=AddElement(pInsert,DOUBLEFOX_DRAW,false,false); //for undo/redo CActionListItem* pAction=new CActionListItem(GetDoc(), ID_EDIT_GROUP); //for 增加符号 pAction->AddMarkAddItem(pNewXy); //插入符号元素 COne* pOne=GetDoc()->GetDraw()->GetAt(pos); pAction->AddAddItem(pOne); //为了恢复元素 pAction->AddDeleteItem(m_selection); GetDoc()->SetActionItem(pAction); Select(pos); ReloadTrackerPath(); return pos; } BOOL CItemSelect::UngroupAll(int& layerCount) { CPositionList* plist = &m_selection; if (plist == NULL) return false; CSigmaDoc * pDoc = GetDoc(); vector vecPositions; int nSelectCount = plist->GetCount(); for (int i = 0; i < nSelectCount; i++) { POSITION pos = plist->FindIndex(i); POSITION posOne = (POSITION)plist->GetAt(pos); //COne* pOne = pDoc->GetDraw()->GetAt(posOne); vecPositions.push_back(posOne); } CPositionList addListAll, deleteListAll; for (auto iter = vecPositions.begin(); iter != vecPositions.end(); ++iter) { CPositionList addList; POSITION pos = *iter; COne* pOne = pDoc->GetDraw()->GetAt(pos); //pOne = *iter; // pDoc->GetDraw()->GetAt(pos); switch (pOne->GetType()) { case DOUBLEFOX_NET: case DOUBLEFOX_GRID: { CNet* pNet = (CNet*)pOne->GetValue(); pNet->Dissolution(pDoc->GetDraw(), addList); } break; case DOUBLEFOX_SCALERULER: { CScaleRuler* psr = (CScaleRuler*)pOne->GetValue(); psr->Dissolution(pDoc->GetDraw(), addList, pOne->color); } break; case DOUBLEFOX_BLOCK: case DOUBLEFOX_PATHFILL: case DOUBLEFOX_3D_FAULTSURFACE: { //CPathFill* pp=(CPathFill*)pOne->GetValue(); //pp->Dissolution(pDoc->GetDraw(), addList, pos); } UngroupSymbol(pos, true, layerCount); //addList.AddTail(pos); break; case DOUBLEFOX_DRAW: UngroupSymbol(pos, false, layerCount); break; default: break; } int nCount = addList.GetCount(); if (nCount > 0)//for undo redo { for (int i = 0; i < nCount; i++) { addListAll.AddTail(addList.GetAt(addList.FindIndex(i))); } deleteListAll.AddTail(pos); addList.RemoveAll(); } } if (addListAll.GetCount() > 0)//for undo redo { CActionListItem* pAction = new CActionListItem(pDoc, IDS_STRING_DISSOLUTION_ELEMENT); pAction->AddAddItem(addListAll); //删除源元素 pAction->AddDeleteItem(deleteListAll); pDoc->SetActionItem(pAction); } Select(NULL); return true; } BOOL CItemSelect::UngroupSymbol(POSITION pos, bool nReplaceExist, int& layerCount) { CSigmaDoc * pDoc = GetDoc(); COne* pOne = GetDoc()->GetDraw()->GetAt(pos); CXy* pxy = NULL; bool bDelXy = false; switch(pOne->GetType()) { //case DOUBLEFOX_INSERT: case DOUBLEFOX_DRAW: { CInsertDraw* pInsert=(CInsertDraw*)pOne->GetValue(); //创建并解散指定的符号 pxy = (CXy*)pInsert->CreateUngroupXY(); bDelXy = true; } break; case DOUBLEFOX_BLOCK: case DOUBLEFOX_PATHFILL: case DOUBLEFOX_3D_FAULTSURFACE: { CXyBlock* pb = (CXyBlock*)pOne->GetValue(); pxy = (CXy*)pb->GetXy(); } break; } if(pxy==NULL) return FALSE; //备份当前类别名称 CString strCurLayer=GetDoc()->GetDraw()->GetCurrentLayer()->GetPathName(); //合并解散后的符号 CPositionList plAdd; CPtrList layerList, markList; if(!nReplaceExist) { CString headLayer = pOne->GetName() + "\\"; CString sn; int i=0; while(GetDoc()->GetDraw()->FindLayer(headLayer)!=NULL) { i++; sn.Format("_%ld", i); headLayer += sn; } if(pxy->GetClassList()->GetCount()==1) //当仅为一个时,为了避免层修饰的合并问题 { CLayerList* pll=pxy->GetClassList()->GetHead(); pll->AddHeadLayer(headLayer); pll->SetName("Layer"); //pll->SetName(pInsert->GetName()); } else // 多个时 { POSITION ptHead=pxy->GetClassList()->AddHead("Layer"); POSITION ptCur; CLayerList* pll; POSITION pt=pxy->GetClassList()->GetHeadPosition(); while(pt) { ptCur=pt; pll=pxy->GetClassList()->GetNext(pt); if(ptCur==ptHead) continue; pll->AddHeadLayer(headLayer + pll->GetClassName() + "\\"); pxy->GetClassList()->MoveClass(ptHead, ptCur); pxy->GetClassList()->RemoveAt(ptCur); } } } GetDoc()->GetDraw()->MoveIn(pxy, plAdd, NULL, &markList, &layerList, true, nReplaceExist); if(bDelXy) delete pxy; if(plAdd.GetCount()==0 && layerList.GetCount()==0 && markList.GetCount()==0) return FALSE; //Select(NULL); //for REDO/UNDO POSITION pt; CPositionList plDel; CActionListItem* pAction=new CActionListItem(GetDoc(), ID_EDIT_UNGROUP); //符号增加,获得的每个符号都是之前的文件没有的 if(markList.GetCount()>0) { CActionMarkAddItem* pMarkAddAction=new CActionMarkAddItem(GetDoc(), 0); CXy* pNewXy; pt=markList.GetHeadPosition(); while(pt) { pNewXy=(CXy*)markList.GetNext(pt); pMarkAddAction->AddMark(pNewXy); } pAction->AddTailItem(pMarkAddAction); } //层位增加 if(layerList.GetCount()>0) { CLayer* pNewLayer; pt=layerList.GetHeadPosition(); while(pt) { pNewLayer=(CLayer*)layerList.GetNext(pt); pAction->AddLayerAddItem(pNewLayer, strCurLayer); } } //元素删除操作 plDel.AddTail(pos); pAction->AddDeleteItem(plDel); //元素增加操作 CActionAddItem* pItem=new CActionAddItem(GetDoc(), 0, plAdd); pAction->AddTailItem(pItem); GetDoc()->SetActionItem(pAction); layerCount = layerList.GetCount(); //CMainFrame* pmf = (CMainFrame*)GetDoc()->GetMainFrame(); //if(layerList.GetCount()>0) //{ // pmf->LoadLayer(GetDoc()->GetDraw()); // if(pmf->m_paneMarkManager.m_treeList.Tree_IsCurrentItem()) // pmf->m_paneMarkManager.ReflashList(); //} return TRUE; } int CItemSelect::GetSelectedCount(void) { return (int)m_selection.GetCount(); } bool CItemSelect::GetPointsZRange(double& zMin, double& zMax) { if (m_selection.IsEmpty()) { return false; } zMin = 1E301; zMax = -1E301; POSITION pos = m_selection.GetHeadPosition(); POSITION pt; COne* pOne; while (pos != NULL) { pt = m_selection.GetNext(pos); pOne = (COne*)GetDoc()->GetDraw()->GetAt(pt); switch (pOne->GetType()) { case DOUBLEFOX_XYZ: case DOUBLEFOX_POINT: { CPointNameEx* pPoint = (CPointNameEx*)pOne->GetValue(); if (pPoint->z0 > zMax) { zMax = pPoint->z0; } if (pPoint->z0 < zMin) { zMin = pPoint->z0; } } break; } } return true; } bool CItemSelect::SetPointsColor(CString colorItemsData, double dWidth, double dHeight) { CColorBase color; CColorItem item; CPoint2D pt; int nCount = color.GetColor().size(); color.GetColor().remove(0, nCount); nCount = color.GetAlpha().size(); color.GetAlpha().remove(0, nCount); int iStart = 0; CString strZ,strR, strG, strB, strT,strContinue; BYTE r, g, b, t; while (1) { CString subItem = colorItemsData.Tokenize(_T("\r\n"), iStart); if (subItem.IsEmpty()) break; AfxExtractSubString(strZ, subItem, 0, _T(',')); AfxExtractSubString(strR, subItem, 1, _T(',')); AfxExtractSubString(strG, subItem, 2, _T(',')); AfxExtractSubString(strB, subItem, 3, _T(',')); AfxExtractSubString(strT, subItem, 4, _T(',')); AfxExtractSubString(strContinue, subItem, 5, _T(',')); item.z = atof(strZ); r = (BYTE)atol(strR); g = (BYTE)atol(strG); b = (BYTE)atol(strB); t = (BYTE)atol(strT); item.m_bContinue = TRUE; item.SetColor(r, g, b, t); color.GetColor().add(item); } CSize sizeMark(dWidth, dHeight); CSize sizeWord(0, 0); POSITION pos = m_selection.GetHeadPosition(); POSITION posCur; COne* pOne; while (pos != NULL) { posCur = m_selection.GetNext(pos); pOne = (COne*)GetDoc()->GetDraw()->GetAt(posCur); switch (pOne->GetType()) { case DOUBLEFOX_XYZ: case DOUBLEFOX_POINT: { CPointNameEx* pPoint = (CPointNameEx*)pOne->GetValue(); if (pOne->HowToViewPoint == nullptr) { pOne->HowToViewPoint = new CHowToViewPoint; } pOne->HowToViewPoint->frColor = color.GetColor(pPoint->z0); pOne->HowToViewPoint->m_mark = sizeMark; pOne->HowToViewPoint->m_word = sizeWord; pOne->HowToViewPoint->SetNullSymbolMode(INSERT_DRAW_CIRCLE); } break; } } return true; } //BOOL CItemInsertDraw::UngroupSelection() //{ // CItemSelect* pSelectItem=GetDoc()->GetSelectItem(); // if(pSelectItem==NULL) return FALSE; // CList* ps=&pSelectItem->m_selection; // if(ps->IsEmpty()) return FALSE; // // POSITION pos=ps->GetHead(); // COne* pOne=GetDoc()->GetDraw()->GetAt(pos); // CInsertDraw* pInsert=(CInsertDraw*)pOne->GetValue(); // CXy* pxy=(CXy*)pInsert->pDraw; // if(pxy==NULL) return FALSE; // // pSelectItem->Select(NULL); // // double dx=pInsert->m_size.cx/fabs(pInsert->rect.Width()); // double dy=pInsert->m_size.cy/fabs(pInsert->rect.Height()); // // CPositionList plDel, plAdd; // // //CRect8 rect; // POSITION p,p1; // // //改变符号大小 // //pxy->GetClassList()->SetScale(dx, dy); // pxy->Scale(pInsert->rect.left, pInsert->rect.bottom,dx,dy); // if(fabs(pInsert->angle)>1e-10) // pxy->Rotate(pInsert->rect.left, pInsert->rect.bottom, pInsert->angle); // // CActionListItem* pAction=new CActionListItem(GetDoc(), ID_EDIT_UNGROUP); // // //增加使用的符号 // CStringList sl; // CString strMarkName; // CXy* pFindXy; // CXy* pNewXy; // pxy->GetNewUsing(sl); // POSITION pt=sl.GetHeadPosition(); // while(pt) // { // strMarkName=sl.GetNext(pt); // pFindXy=(CXy*)GetDoc()->GetDraw()->FindMark(strMarkName); // if(pFindXy) //当前文件中有该符号 // { // } // else //当前文件中没有该符号 // { // pFindXy=(CXy*)pxy->FindMark(strMarkName); // if(pFindXy) // { // pNewXy=new CXy; // *pNewXy=*pFindXy; // GetDoc()->GetDraw()->AddMark(pNewXy); // pAction->AddMarkAddItem(pNewXy); // } // } // } // // //增加类别 // int layerCount=0; // CLayer* pLayer; // CLayerList* pClass; // // //增加元素 // COne *pNewOne; // p=pxy->GetValueList()->GetHeadPosition(); // while(p) // { // pOne=(COne *)(pxy->GetValueList()->GetNext(p)); // pNewOne=new COne(); // *pNewOne=*pOne; // pNewOne->SetScale(dx, dy, TRUE, TRUE); // pNewOne->Offset(pInsert->x0-pInsert->rect.left,pInsert->y0-pInsert->rect.bottom); // pNewOne->PositionNew(0); // // pClass=GetDoc()->GetDraw()->GetClass(pOne->GetLayer()->GetClassName()); // if(pClass==NULL) // pClass=GetDoc()->GetDraw()->AddClass(pOne->GetLayer()->GetClassName()); // // pLayer=GetDoc()->GetDraw()->FindLayer(pOne->GetLayer()->GetPathName()); // if(pLayer) // pNewOne->SetLayer(pLayer); // else // { // pLayer=new CLayer; // *pLayer=*(pOne->GetLayer()); // pLayer->SetParentClass(pClass); // pNewOne->SetLayer(pLayer); // GetDoc()->GetDraw()->AddLayer(pLayer); // pLayer->SetScale(dx, dy); // pLayer->PositionNew(0); // // pAction->AddLayerAddItem(pLayer, GetDoc()->GetDraw()->GetCurrentLayer()->GetPathName()); // layerCount++; // } // p1=GetDoc()->GetDraw()->InsertElementBefore(pos,pNewOne); // if(p1) // { // pSelectItem->Select(p1,TRUE); // plAdd.AddTail(p1); // } // } // // //恢复符号的大小 // if(fabs(pInsert->angle)>1e-10) // pxy->Rotate(pInsert->rect.left, pInsert->rect.bottom, -pInsert->angle); // pxy->Scale(pInsert->rect.left, pInsert->rect.bottom,1/dx,1/dy); // //pxy->GetClassList()->SetScale(1/dx, 1/dy); // pSelectItem->ReloadTrackerPath(); // // //for undo/redo // //CActionListItem *pAction=new CActionListItem(GetDoc(), ID_EDIT_UNGROUP); // //元素删除操作 // plDel.AddTail(pos); // pAction->AddDeleteItem(plDel); // //元素增加操作 // CActionAddItem* pItem=new CActionAddItem(GetDoc(), 0, plAdd); // pAction->AddItem(pItem); // GetDoc()->SetActionItem(pAction); // // CMainFrame* pmf = (CMainFrame*)GetDoc()->GetMainFrame(); // if(layerCount>0 && pmf!=NULL) // { // pmf->LoadLayer(GetDoc()->GetDraw()); // //if(pmf->m_paneMarkManager.m_treeList.Tree_IsCurrentItem()) // // pmf->m_paneMarkManager.ReflashList(); // } // return TRUE; //} int CItemSelect::FindNeedRemovePoints(const std::vector &removedPoints, CPositionList &needRemoved) { CXy* pXy = GetDoc()->m_pXy; for (POSITION pos = (*pXy->GetValueList()).GetHeadPosition(); pos != nullptr; (*pXy->GetValueList()).GetNext(pos)) { COne *pOne = pXy->GetAt(pos); int type = pOne->GetType(); if (type == DOUBLEFOX_POINT || type == DOUBLEFOX_XYZ) { CPointNameEx* ppn = (CPointNameEx*)pOne->GetValue(); CPointXYZ pointXYZ = CPointNameExToCPointXYZ(*ppn); if (CPointXYZContains(removedPoints, pointXYZ)) { needRemoved.AddTail(pos); } } } return needRemoved.GetCount(); } bool CItemSelect::CPointXYZIdxContains(const std::vector &points, const CPointXYZ &point) { for (const CPointXYZ& xyz : points) { if (IsEqual(xyz.x0, point.x0) && IsEqual(xyz.y0, point.y0) && IsEqual(xyz.z0, point.z0)) { return true; } } return false; } CString NItem::CItemSelect::RemoveSuperSubscript(const CString& text) { CString result = text; // 去掉上下标开头和结止符 result.Replace("^u0.5 ", ""); result.Replace("^d0.5 ", ""); result.Replace("^n", ""); return result; } CString NItem::CItemSelect::GetSuperSubscript(const CString& text) { CString result; int iStart = 0; int iEnd = 0; // 去掉上下标开头和结止符 while (true) { iStart = text.Find("^u0.5 ", iEnd); if (iStart == -1) { iStart = text.Find("^d0.5 ", iEnd); } if (iStart == -1) { break; } iEnd = text.Find("^n", iStart); if (iEnd == -1) { break; } result += text.Mid(iStart + 5, iEnd - (iStart + 5)); } return result; }