#include #include "stdafx.h" #include "SigmaView.h" #include "DrawBend.h" #include "SectionDoc.h" #include "Item.h" #include "ItemSelect.h" #include "ItemEraser.h" #include "ActionDeleteLayerItem.h" #include "ActionComboItem.h" #include "ActionLayerDragDropItem.h" #include "ItemPointAdd.h" #include "ActionAddItem.h" #include "ItemScaleEmbellish.h" #include "./spdlog/spdlog.h" #include "ItemSolid.h" #include "./spdlog/sinks/rotating_file_sink.h" #include "QTransformTracker.h" #include "ActionListItem.h" #include "ActionEmbellishItem.h" #include "ActionLayerRenameItem.h" #include "actionaddlayeritem.h" #include "ActionChangeLayerItem.h" #include "ActionReverseZItem.h" #include "ItemExportFile.h" #include "StatusDefine.h" #include "TinyXml/tinyxml.h" #include "DoubleComparator.h" #include "UndoManager/UndoManager.h" #include #include #include #include #include "vtkInterface.h" #include "Interface.h" #include "DrawOperator/FileUtility.h" #include "WellPoleLib/WellPoleInitCShap.h" #include "MultiWellSectionLib/MVSectionInitCShap.h" #include "DrawOperator/Util.h" #include "ObjectProxyFactory.h" #include "DrawOperator/MapViewLayer.h" //#include "PolygonTreeInterface.h" //#include "InterfaceElements.h" static bool bInitLog = false; static bool bInitDump = false; long __stdcall CrashInfocallback(_EXCEPTION_POINTERS *pexcp); static void InitLog(); /** * 这个库并不需要真正的初始化,问题在 C# 调用 C++ 动态库时是懒加载,第一次调用动态库中的函数时才会加载, * 如果加载失败,这时候才会报出来,所以让 C# 程序在一开始时就调用这个函数一次,如果动态库不完整,可以在 * 打开程序的第一时间发现 * */ extern "C" __declspec(dllexport) void GeoSigmaLibInit() { WellPoleLibInit_CSHAP(); MultiWellSectionLibInit_CSHAP(); TRACE("GeoSigmaLibInit\n"); } extern "C" __declspec(dllexport) BOOL PointerFree(void* p) { if (p != nullptr) { free(p); p = nullptr; } return true; } extern "C" __declspec(dllexport) BOOL PointerDelete(void* p) { if (p != nullptr) { delete p; p = nullptr; } return true; } extern "C" __declspec(dllexport) BOOL PointerArrayDelete(void* p) { delete[] p; p = nullptr; return true; } extern "C" __declspec(dllexport) BOOL TestFunSigma(LPCTSTR strInput) { AfxMessageBox(strInput); return 0; } extern "C" __declspec(dllexport) bool DestroyView(CSigmaView* pView) { if (pView != nullptr) { delete pView; pView = nullptr; } //if (pSectionDoc != nullptr) { // delete pSectionDoc; // pSectionDoc = nullptr; //} return true; } extern "C" __declspec(dllexport) CSigmaView* CreateView() { //if (!bInitDump) //{ // //::SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)CrashInfocallback); // bInitDump = true; // InitLog(); //} CSigmaView* pView = new CSigmaView(); return pView; } // 是否允许进行旋转编辑 extern "C" __declspec(dllexport) void EnableRotateEdit(CSigmaView* pView, bool enable) { if (pView == nullptr) { return; } pView->SetEnableRotate(enable); } extern "C" __declspec(dllexport) CSigmaView* CreateViewByXy(CXy* pXy) { CSigmaView* pView = new CSigmaView(pXy); return pView; } extern "C" __declspec(dllexport) void* GetDrawerXy(CSigmaView* pView) { if (pView->m_pDoc->m_pXy == NULL) return 0; return pView->m_pDoc->m_pXy; } BOOL SaveAs(CDC* pDC, const wchar_t* lpszFilename); extern "C" __declspec(dllexport) void SetScreenDC(CSigmaView* pView, HDC hdcMem) { CDC *pDC = CDC::FromHandle(hdcMem); //SaveAs(pDC, L"C:\\tmpScree.bmp"); pView->SetScreenDC(pDC); } extern "C" __declspec(dllexport) void SetImgDC(CSigmaView* pView, HDC hdcMem) { CDC *pDC = CDC::FromHandle(hdcMem); //SaveAs(pDC, L"C:\\tmpSet.bmp"); pView->SetImgDc(pDC); } static CMesh* GetMesh(CSigmaView* pView); extern "C" __declspec(dllexport) double GetKevMeshMaxScale(CSigmaView* pView, KevVtkMeshData* pMesh) { double ret = -1; if (pView == nullptr) { TRACE("pView为空\n"); return ret; } CSigmaDoc* pDoc = pView->m_pDoc; CXyDC* pXyDC = &pDoc->GetDC(); CXy* pXy = pDoc->m_pXy; if (pMesh == nullptr) { TRACE("未找到网格\n"); return ret; } int scaleArr[16] = { 100,200,500,1000,2000,5000,10000,20000,25000,50000,100000,200000,500000,1000000,2000000,5000000 }; double width = pMesh->dx*(pMesh->numX - 1); double height = pMesh->dy*(pMesh->numY - 1); int maxPixelNum = (100 * 1024 * 1024) / 4; int length = sizeof(scaleArr) / sizeof(scaleArr[0]); double scale = 1; double screenWidth = 1; double screenHeight = 1; for (int i = 0; i < length; i++) { scale = 1.0f / (scaleArr[i] / 1000.0f); pXyDC->SetScale(scale, scale); pXy->SetUnit(1, 1); screenWidth = pXyDC->GetScreenWidth(width); screenHeight = abs(pXyDC->GetScreenHeight(height)); double num = screenWidth * screenHeight; if (num > maxPixelNum) { continue; } else { ret = scale; break; } } return ret; } extern "C" __declspec(dllexport) double GetFirstMeshMaxScale(CSigmaView* pView) { double ret = -1; if (pView == nullptr) { TRACE("pView为空\n"); return ret; } CSigmaDoc* pDoc = pView->m_pDoc; CXyDC* pXyDC = &pDoc->GetDC(); CXy* pXy = pDoc->m_pXy; if (pXy->GetCount() <= 0) { TRACE("图件中不包含任何元素\n"); return ret; } CMesh* pMesh = GetMesh(pView); if (pMesh == nullptr) { TRACE("未找到网格\n"); return ret; } int scaleArr[16] = { 100,200,500,1000,2000,5000,10000,20000,25000,50000,100000,200000,500000,1000000,2000000,5000000}; double width = pMesh->Width(); double height = pMesh->Height(); int maxPixelNum = (50 * 1024 * 1024) / 4; int length = sizeof(scaleArr) / sizeof(scaleArr[0]); double scale = 1; double screenWidth = 1; double screenHeight = 1; for (int i = 0; i < length; i++) { scale = 1.0f / (scaleArr[i] / 1000.0f); pXyDC->SetScale(scale, scale); pXy->SetUnit(1, 1); screenWidth = pXyDC->GetScreenWidth(width); screenHeight = abs(pXyDC->GetScreenHeight(height)); double num = screenWidth * screenHeight; if (num > maxPixelNum) { continue; } else { ret = scale; break; } } return ret; } /** * 获取KEV网格的最大分辨率图像 * * \param pView * \return */ extern "C" __declspec(dllexport) HBITMAP GetKevMeshImage(CSigmaView* pView, KevVtkMeshData* pMeshData) { if (pView == nullptr) { TRACE("pView为空\n"); return nullptr; } CSigmaDoc* pDoc = pView->m_pDoc; CXyDC* pXyDC = &pDoc->GetDC(); CXy* pXy = pDoc->m_pXy; if (pXy->GetCount() <= 0) { TRACE("图件中不包含任何元素\n"); return nullptr; } if (pMeshData == nullptr) { TRACE("网格为空\n"); return nullptr; } double scale = GetKevMeshMaxScale(pView, pMeshData); if (scale < 0) { TRACE("没有合适的比例\n"); return nullptr; } double width = pMeshData->dx*(pMeshData->numX -1); double height = pMeshData->dy*(pMeshData->numY - 1); double left = pMeshData->P0[0]; double right = pMeshData->P0[0] + width; double bottom = pMeshData->P0[1]; double top = bottom + height; NBase::CRect8 meshRect; meshRect.bottom = bottom; meshRect.top = top; meshRect.left = left; meshRect.right = right; pXyDC->SetScale(scale, scale); pXy->SetUnit(1, 1); double screenWidth = pXyDC->GetScreenWidth(width); double screenHeight = abs(pXyDC->GetScreenHeight(height)); if (screenWidth < 2 || screenHeight < 2) { return nullptr; } CSize screenSize(screenWidth, screenHeight); CDC dc; dc.CreateCompatibleDC(NULL); CXyDC pDC; pDC.Create(&dc, false); pDC.SetAntiAlias(true); int planes = dc.GetDeviceCaps(PLANES);// 颜色平面数 int bpp = dc.GetDeviceCaps(BITSPIXEL);// 颜色像素值 CBitmap *pBitmap, *pOldBitmap; pBitmap = new CBitmap(); pBitmap->CreateBitmap(screenSize.cx, screenSize.cy, planes, bpp, NULL); pOldBitmap = dc.SelectObject(pBitmap); dc.FillSolidRect(0, 0, screenSize.cx, screenSize.cy, RGB(255, 255, 255)); if (pXy->GetCount() > 0) { CRect rt(0, 0, screenSize.cx, screenSize.cy); pDC.Extend(meshRect, rt, EXTEND_MODE_CENTER); pDC.SetViewRect(rt); // FIXME: 目前的截图,开启抗锯齿,符号充填,符号会超出范围,图件本身开不开户抗锯齿都不影响,还没找到原因 pDC.SetAntiAlias(true); pXy->Draw(pDC); } ////保存为文件 //CImage image; //image.Attach(*pBitmap); //CString filePath = "./FirstMeshImage.bmp"; //image.Save(filePath); //image.Detach(); dc.SelectObject(pOldBitmap); HBITMAP hBit = (HBITMAP)pBitmap->Detach(); delete pBitmap; dc.DeleteDC(); return hBit; } /** * 获取第一个网格的最大分辨率图像 * * \param pView 图件 * \return */ extern "C" __declspec(dllexport) HBITMAP GetFirstMeshImage(CSigmaView* pView) { if (pView == nullptr) { TRACE("pView为空\n"); return nullptr; } CSigmaDoc* pDoc = pView->m_pDoc; CXyDC* pXyDC = &pDoc->GetDC(); CXy* pXy = pDoc->m_pXy; if (pXy->GetCount() <= 0) { TRACE("图件中不包含任何元素\n"); return nullptr; } CMesh* pMesh = GetMesh(pView); if (pMesh == nullptr) { TRACE("未找到网格\n"); return nullptr; } double scale = GetFirstMeshMaxScale(pView); if (scale < 0) { TRACE("没有合适的比例\n"); return nullptr; } NBase::CRect8 meshRect = pMesh->GetRect(); double width = meshRect.Width(); double height = meshRect.Height(); double left = meshRect.left; double right = meshRect.right; double top = meshRect.top; double bottom = meshRect.bottom; pXyDC->SetScale(scale, scale); pXy->SetUnit(1, 1); double screenWidth = pXyDC->GetScreenWidth(width); double screenHeight = abs(pXyDC->GetScreenHeight(height)); if (screenWidth < 2 || screenHeight < 2) { return nullptr; } CSize screenSize(screenWidth, screenHeight); CDC dc; dc.CreateCompatibleDC(NULL); CXyDC pDC; pDC.Create(&dc, false); pDC.SetAntiAlias(true); int planes = dc.GetDeviceCaps(PLANES);// 颜色平面数 int bpp = dc.GetDeviceCaps(BITSPIXEL);// 颜色像素值 CBitmap *pBitmap, *pOldBitmap; pBitmap = new CBitmap(); pBitmap->CreateBitmap(screenSize.cx, screenSize.cy, planes, bpp, NULL); pOldBitmap = dc.SelectObject(pBitmap); dc.FillSolidRect(0, 0, screenSize.cx, screenSize.cy, RGB(255, 255, 255)); if (pXy->GetCount() > 0) { CRect rt(0, 0, screenSize.cx, screenSize.cy); pDC.Extend(meshRect, rt, EXTEND_MODE_CENTER); pDC.SetViewRect(rt); // FIXME: 目前的截图,开启抗锯齿,符号充填,符号会超出范围,图件本身开不开户抗锯齿都不影响,还没找到原因 pDC.SetAntiAlias(true); pXy->Draw(pDC); } ////保存为文件 //CImage image; //image.Attach(*pBitmap); //CString filePath = "./FirstMeshImage.bmp"; //image.Save(filePath); //image.Detach(); dc.SelectObject(pOldBitmap); HBITMAP hBit = (HBITMAP)pBitmap->Detach(); dc.DeleteDC(); delete pBitmap; return hBit; } /** * 根据指定的网格范围生成网格图像. * * @param pView * @param left * @param top * @param right * @param bottom * @return */ extern "C" __declspec(dllexport) HBITMAP DrawImageBmp(CSigmaView* pView, double left, double top, double right, double bottom) { CSigmaDoc* pDoc = pView->m_pDoc; CXyDC* pXyDC = &pDoc->GetDC(); CXy* pXy = pDoc->m_pXy; if (pXy->GetCount() <= 0) { return nullptr; } //获得导出图件的大小 NBase::CRect8 rect(1e100, -1e100, -1e100, 1e100); if (left == right || top == bottom) { pView->m_pDoc->GetDrawRange(rect); } else { rect.SetRect(left, top, right, bottom); } double dx = rect.Width(); double dy = rect.Height(); if (dx < 1e-20 || dy < 1e-20) { return nullptr; } CSize sz(pXyDC->GetScreenWidth(dx), abs(pXyDC->GetScreenHeight(dy))); CDC dc; dc.CreateCompatibleDC(NULL); CXyDC pDC; pDC.Create(&dc, false); pDC.SetAntiAlias(true); int planes = dc.GetDeviceCaps(PLANES); int bpp = dc.GetDeviceCaps(BITSPIXEL); CBitmap *pBitmap, *pOldBitmap; pBitmap = new CBitmap(); pBitmap->CreateBitmap(sz.cx, sz.cy, planes, bpp, NULL); pOldBitmap = dc.SelectObject(pBitmap); dc.FillSolidRect(0, 0, sz.cx, sz.cy, RGB(255, 255, 255)); if (pXy->GetCount() > 0) { CRect rt(0, 0, sz.cx, sz.cy); pDC.Extend(rect, rt, EXTEND_MODE_CENTER); pDC.SetViewRect(rt); // FIXME: 目前的截图,开启抗锯齿,符号充填,符号会超出范围,图件本身开不开户抗锯齿都不影响,还没找到原因 pDC.SetAntiAlias(true); pXy->Draw(pDC); } dc.SelectObject(pOldBitmap); HBITMAP hBit = (HBITMAP)pBitmap->Detach(); pBitmap->DeleteObject(); dc.DeleteDC(); delete pBitmap; return hBit; } extern "C" __declspec(dllexport) void SetViewBackcolor(CSigmaView* pView, int r, int g, int b) { pView->SetBackColor(RGB(r, g, b)); } extern "C" __declspec(dllexport) void GetViewBackcolor(CSigmaView* pView, int& r, int& g, int& b) { COLORREF colRef = pView->GetBackColor(); r = GetRValue(colRef); g = GetGValue(colRef); b = GetBValue(colRef); } extern "C" __declspec(dllexport) void SetSymbolView(CSigmaView* pView, BOOL isSymbolView) { pView->SetSymbolView(isSymbolView); } extern "C" __declspec(dllexport) void CombinImgDC(CSigmaView* pView, int x, int y, int width, int height, int screenX, int screenY) { //CImage imag; //imag.Create(width, height, 32); ////将CDC搬移到imag //BitBlt(imag.GetDC(), 0, 0, width, height, hdcMem, 0, 0, SRCCOPY); //HRESULT hResult = imag.Save(_T("c:\\new.jpg")); //imag.ReleaseDC(); pView->CombinImg(x, y, width, height, screenX, screenY); } extern "C" __declspec(dllexport) void SetImgDCAndSize(CSigmaView* pView, HDC hdcMem, int left, int top, int right, int bottom) { CDC *pDC = CDC::FromHandle(hdcMem); //int nHDpi = pDC->GetDeviceCaps(HORZSIZE); //int nVDpi= pDC->GetDeviceCaps(VERTSIZE); pView->SetImgDc(pDC); pView->SetClient(left, top, right, bottom); } extern "C" __declspec(dllexport) void SetAntiAlias(CSigmaView* pView, bool enable) { pView->SetAntiAlias(enable); } extern "C" __declspec(dllexport) bool GetAntiAlias(CSigmaView* pView) { return pView->GetAntiAlias(); } extern "C" __declspec(dllexport) void SetPrinting(CSigmaView* pView, bool isPriting) { pView->SetPrinting(isPriting); } extern "C" __declspec(dllexport) bool GetIsPriting(CSigmaView* pView) { return pView->GetIsPriting(); } extern "C" __declspec(dllexport) void SetViewRect(CSigmaView* pView, int left, int top, int right, int bottom) { pView->SetClient(left, top, right, bottom); } extern "C" __declspec(dllexport) void InitializeImg(CSigmaView* pView, HDC hdcMem, int left, int top, int right, int bottom) { SetImgDCAndSize(pView, hdcMem, left, top, right, bottom); pView->InitialView(); } extern "C" __declspec(dllexport) bool DrawImg(CSigmaView* pView, bool symbolViewFlag) { return pView->DrawImg(symbolViewFlag); } extern "C" __declspec(dllexport) bool DrawOther(CSigmaView* pView, HDC hdcMem) { CDC *pDC = CDC::FromHandle(hdcMem); pView->OnDrawOther(pDC); return true; } extern "C" __declspec(dllexport) void Sigma_UndoView(CSigmaView* pView) { if (pView->m_pDoc == 0) return; pView->m_pDoc->PopDC(); CItemSelect* pItemSelect = pView->m_pDoc->GetSelectItem(); if (pItemSelect != nullptr) { pItemSelect->ReloadTrackerPath(); } } extern "C" __declspec(dllexport) int GeoSigma_GetZoomStackCount(CSigmaView * pView) { if (pView->m_pDoc == 0) return -1; return pView->m_pDoc->GetZoomStackCount(); } extern "C" __declspec(dllexport) void Sigma_DrawAssistant(CSigmaView* pView, int mouseX, int mouseY, HDC hdc) { if (pView == 0) return; if (pView->m_pDoc == 0) return; CDC * pDC = CDC::FromHandle(hdc); if (pDC == 0) return; NItem::CItem * pItem = pView->m_pDoc->GetItem(); if (pItem == 0) return; pItem->DrawAssistant(pDC, mouseX, mouseY); } extern "C" __declspec(dllexport) void SigmaViewShowBKGrid(CSigmaView * pView, int bShow) { if (pView == nullptr) return; pView->ShowBKGrid(bShow == 0 ? false : true); } extern "C" __declspec(dllexport) void SetViewDC(CSigmaView* pView, HDC hdcMem, int left, int top, int right, int bottom) { CDC *pDC = CDC::FromHandle(hdcMem); //CDC *pDC = new CDC; //pDC->Attach(hdcMem); pView->SetDc(pDC); pView->SetClient(left, top, right, bottom); //pDC->Detach(); //pDC->DeleteDC(); } extern "C" __declspec(dllexport) CSigmaView* CreateViewWithDC(HDC hdcMem, int left, int top, int right, int bottom) { //if (pSectionDoc == nullptr) //{ // pSectionDoc = new CSectionDoc(); //} //HDC hDC = ::GetDC(handAddress); CSigmaView* pView = new CSigmaView(); SetViewDC(pView, hdcMem, left, top, right, bottom); //CDC *pDC = CDC::FromHandle(hdcMem); //pView->SetDc(pDC); //pView->SetClient(left, top, right, bottom); return pView; } extern "C" __declspec(dllexport) CSigmaView* CreateViewWithXyDC(CXy* pXy, HDC hdcMem, int left, int top, int right, int bottom) { CSigmaView* pView = new CSigmaView(pXy); SetViewDC(pView, hdcMem, left, top, right, bottom); return pView; } extern "C" __declspec(dllexport) HDC GetViewDC(CSigmaView* pView) { if (pView == nullptr || pView->m_pDC == nullptr) return nullptr; return pView->m_pDC->GetSafeHdc(); } extern "C" __declspec(dllexport) void EnableRedraw(CSigmaView* pView, bool enable) { pView->m_pDoc->EnableRedraw(enable); } extern "C" __declspec(dllexport) void SetHWND(CSigmaView * pView, HWND hwnd) { pView->SetHWND(hwnd); } extern "C" __declspec(dllexport) void Initialize(CSigmaView* pView, HDC hdcMem, int left, int top, int right, int bottom) { SetViewDC(pView, hdcMem, left, top, right, bottom); pView->InitialView(); } extern "C" __declspec(dllexport) void GetMapRange(CSigmaView* pView, double& left, double& top, double& right, double& bottom) { if (pView->m_pDoc->m_pXy == NULL) { return; } NBase::CRect8 rect = pView->m_pDoc->m_pXy->m_range; left = rect.left; top = rect.top; right = rect.right; bottom = rect.bottom; } extern "C" __declspec(dllexport) int GetElementCount(CSigmaView* pView) { if (pView->m_pDoc->m_pXy == NULL) return 0; return pView->m_pDoc->m_pXy->GetCount(); } extern "C" __declspec(dllexport) void GetScreenReal(CSigmaView* pView, int leftS, int topS, int rightS, int bottomS, double& left, double& top, double& right, double& bottom) { CRect rcScreen(leftS, topS, rightS, bottomS); NBase::CRect8 rcScreenReal = pView->m_pDoc->m_xyDC.GetReal(rcScreen); left = rcScreenReal.left; top = rcScreenReal.top; right = rcScreenReal.right; bottom = rcScreenReal.bottom; } extern "C" __declspec(dllexport) void GetRealScreen(CSigmaView* pView, double leftS, double topS, double rightS, double bottomS, int& left, int& top, int& right, int& bottom) { NBase::CRect8 rcScreen(leftS, topS, rightS, bottomS); CRect rcScreenReal = pView->m_pDoc->m_xyDC.GetScreen(rcScreen); left = rcScreenReal.left; top = rcScreenReal.top; right = rcScreenReal.right; bottom = rcScreenReal.bottom; } extern "C" __declspec(dllexport) double GetRealHeight(CSigmaView* pView, int height) { return pView->m_pDoc->m_xyDC.GetRealHeight((long)height); //一行的实际单位数 } extern "C" __declspec(dllexport) int GetScreenHeight(CSigmaView* pView, double height) { return pView->m_pDoc->m_xyDC.GetScreenHeight(height); //一行的实际单位数 } extern "C" __declspec(dllexport) double GetRealWidth(CSigmaView* pView, int width) { return pView->m_pDoc->m_xyDC.GetRealWidth((long)width); //一行的实际单位数 } extern "C" __declspec(dllexport) int GetScreenWidth(CSigmaView* pView, double width) { return pView->m_pDoc->m_xyDC.GetScreenWidth(width); //一行的实际单位数 } extern "C" __declspec(dllexport) int Sigma_WorldToScreen(CSigmaView * pView, double wx, double wy, int * xOut, int * yOut) { *xOut = *yOut = 0; if (pView->m_pDoc == 0) return -1; CPoint pt = pView->m_pDoc->m_xyDC.GetScreen(wx, wy); *xOut = pt.x; *yOut = pt.y; return 1; } //函数功能:由屏幕坐标转换为世界坐标 extern "C" __declspec(dllexport) int Sigma_ScreenToWorld(CSigmaView * pView, int sx, int sy, double * wxOut, double * wyOut) { *wxOut = *wyOut = 0; if (pView->m_pDoc == 0) return -1; CPoint ptScreen; ptScreen.SetPoint(sx, sy); NBase::CPoint2D pt = pView->m_pDoc->m_xyDC.GetReal(ptScreen); *wxOut = pt.x0; *wyOut = pt.y0; return 1; } extern "C" __declspec(dllexport) void GetDisplayRange(CSigmaView* pView, double& left, double& top, double& right, double& bottom) { NBase::CRect8 rect = pView->m_pDoc->m_pXy->m_display; left = rect.left; top = rect.top; right = rect.right; bottom = rect.bottom; } extern "C" __declspec(dllexport) int OffsetPix(CSigmaView * pView, int offsetX, int offsetY) { double dX = pView->m_pDoc->m_xyDC.GetRealWidth((long)offsetX); double dY = pView->m_pDoc->m_xyDC.GetRealHeight((long)offsetY); pView->m_pDoc->m_xyDC.OffsetRect(-dX, -dY); pView->m_pDoc->Modified(); return 1; } extern "C" __declspec(dllexport) int SetCustomDPI(CSigmaView * pView, double dpi) { pView->m_pDoc->m_xyDC.SetCustomDPI(1, dpi); return 1; } extern "C" __declspec(dllexport) int GetXYScale(CSigmaView * pView, double * xsOut, double * ysOut) { if (pView == 0) return -1; if (pView->m_pDoc == 0) return -1; *xsOut = *ysOut = 0; NBase::CSize8 scale; pView->m_pDoc->GetDC().GetScale(scale.cx, scale.cy); *xsOut = scale.cx; *ysOut = scale.cy; return 1; } extern "C" __declspec(dllexport) int SetXYScale(CSigmaView * pView, double xs, double ys) { if (pView == 0) return -1; if (pView->m_pDoc == 0) return -1; double xsOld = 0; double ysOld = 0; GetXYScale(pView, &xsOld, &ysOld); if (fabs(xs - xsOld) < 1e-8 && fabs(ys - ysOld) < 1e-8) return 1; pView->m_pDoc->GetDC().SetScale(xs, ys); pView->m_pDoc->Modified(); return 1; } extern "C" __declspec(dllexport) int GetXYUnit(CSigmaView * pView, int * xUnitOut, int * yUnitOut) { if (pView == 0) return -1; if (pView->m_pDoc == 0) return -1; *xUnitOut = *yUnitOut = 0; CSize size = pView->m_pDoc->GetDraw()->GetUnit(); *xUnitOut = size.cx; *yUnitOut = size.cy; return 1; } extern "C" __declspec(dllexport) int SetXYUnit(CSigmaView * pView, int xUnit, int yUnit) { if (pView == 0) return -1; if (pView->m_pDoc == 0) return -1; pView->m_pDoc->GetDraw()->SetUnit(xUnit, yUnit); pView->m_pDoc->Modified(); return 1; } extern "C" __declspec(dllexport) BOOL GetPointsZRange(CSigmaView * pView, double& zMin, double& zMax) { return pView->GetPointsZRange(zMin, zMax); } extern "C" __declspec(dllexport) BOOL SetPointsColor(CSigmaView * pView, LPCTSTR colorItemsData, double dWidth, double dHeight) { return pView->SetPointsColor(colorItemsData, dWidth, dHeight); } extern "C" __declspec(dllexport) void SetGridStep(CSigmaView * pView, double stepX, double stepY) { if (pView == nullptr) { return; } pView->GridStepX = stepX; pView->GridStepY = stepY; } extern "C" __declspec(dllexport) void GetGridStep(CSigmaView * pView, double& stepX, double& stepY) { if (pView == nullptr) { return; } stepX = pView->GridStepX; stepY = pView->GridStepY; } extern "C" __declspec(dllexport) int XyGetElementType(CSigmaView* pView, POSITION pos) { if (pView == nullptr) { return -1; } return pView->m_pDoc->m_pXy->GetElementType(pos); } extern "C" __declspec(dllexport) int TestLayersLength(CSigmaView* pView) { if (pView == NULL) return 0; if (pView->m_pDoc == NULL) return 0; CString strLayers; CXy* pxy = pView->m_pDoc->m_pXy; if (pxy == NULL) { return 0; } CLayer* pLayerCurrent; strLayers = _T(""); POSITION pos, posLayer; CLayerList* pLayer; CClassList* pClass = pxy->GetClassList(); pos = pClass->GetHeadPosition(); while (pos) { pLayer = pClass->GetNext(pos); posLayer = pLayer->GetHeadPosition(); while (posLayer) { pLayerCurrent = pLayer->GetNext(posLayer); strLayers.AppendFormat("%d|%s\r\n", pLayerCurrent->GetState(), pLayerCurrent->GetPathName()); } } pView->m_pDoc->InsertParameterPair(CString("Layers"), strLayers); return strLayers.GetLength(); } extern "C" __declspec(dllexport) BOOL XyGetLayers(CXy* pxy, BYTE*& destBuffer, int& destLen, BOOL withStatus) { if (pxy == NULL) { return 0; } CLayer* pLayerCurrent; CString strLayers = _T(""); POSITION pos, posLayer; CLayerList* pLayer; CClassList* pClass = pxy->GetClassList(); pos = pClass->GetHeadPosition(); if (withStatus) { while (pos) { pLayer = pClass->GetNext(pos); posLayer = pLayer->GetHeadPosition(); while (posLayer) { pLayerCurrent = pLayer->GetNext(posLayer); strLayers.AppendFormat("%d|%s\r\n", pLayerCurrent->GetState(), pLayerCurrent->GetPathName()); } } } else { while (pos) { pLayer = pClass->GetNext(pos); posLayer = pLayer->GetHeadPosition(); while (posLayer) { pLayerCurrent = pLayer->GetNext(posLayer); strLayers.AppendFormat("%s\r\n", pLayerCurrent->GetPathName()); } } } destLen = strLayers.GetLength(); CMemFile mf(destLen); mf.Write(strLayers, destLen); // memcpy(destBuffer, strLayers.GetBuffer(0), destLen); destBuffer = mf.Detach(); return TRUE; } extern "C" __declspec(dllexport) BOOL GetLayers(CSigmaView* pView, BYTE*& destBuffer, int& destLen, BOOL withStatus) { if (pView == NULL) return 0; if (pView->m_pDoc == NULL) return 0; CString strLayers; CXy* pxy = pView->m_pDoc->m_pXy; if (pxy == NULL) { return 0; } CLayer* pLayerCurrent; strLayers = _T(""); POSITION pos, posLayer; CLayerList* pLayer; CClassList* pClass = pxy->GetClassList(); pos = pClass->GetHeadPosition(); if (withStatus) { while (pos) { pLayer = pClass->GetNext(pos); posLayer = pLayer->GetHeadPosition(); while (posLayer) { CString name = pLayer->GetPathName(posLayer); pLayerCurrent = pLayer->GetNext(posLayer); strLayers.AppendFormat("%d|%s\r\n", pLayerCurrent->GetState(), pLayerCurrent->GetPathName()); } } } else { while (pos) { pLayer = pClass->GetNext(pos); posLayer = pLayer->GetHeadPosition(); while (posLayer) { pLayerCurrent = pLayer->GetNext(posLayer); strLayers.AppendFormat("%s\r\n", pLayerCurrent->GetPathName()); } } } destLen = strLayers.GetLength(); CMemFile mf(destLen); mf.Write(strLayers, destLen); // memcpy(destBuffer, strLayers.GetBuffer(0), destLen); destBuffer = mf.Detach(); return TRUE; } extern "C" __declspec(dllexport) int GetCurrentLayer(CSigmaView* pView, BYTE* layerName) { CXy* pxy = pView->m_pDoc->m_pXy; CLayer* pLayer = pxy->GetCurrentLayer(); if (pLayer == NULL) { //layerName[0] = '\0'; return 0; } else { // layerName = (LPCTSTR)(pLayer->GetName()); CString strName = pLayer->GetName(); int nLen = strName.GetLength(); memcpy(layerName, strName.GetBuffer(0), nLen); return nLen; } } extern "C" __declspec(dllexport) void SetCurrentLayer(CSigmaView* pView, LPCTSTR layerName) { if (pView == NULL) { return; } CXy* pxy = pView->m_pDoc->m_pXy; pxy->SetCurrentLayer(layerName); } extern "C" __declspec(dllexport) void SetLayerState(CSigmaView* pView, LPCTSTR layerName, int status) { if (pView == NULL) { return; } CXy* pxy = pView->m_pDoc->m_pXy; if (pxy == NULL) { return; } CLayer* pLayer = pxy->FindAddLayer(layerName); //pxy出现为NULL的情况 if (pLayer == NULL) return; pLayer->SetState(status); } extern "C" __declspec(dllexport) int GetLayerState(CSigmaView* pView, LPCTSTR layerName) { if (pView == NULL) { return -1; } CXy* pxy = pView->m_pDoc->m_pXy; if (pxy == NULL) { return -1; } CLayer* pLayer = pxy->FindAddLayer(layerName); //pxy出现为NULL的情况 if (pLayer == NULL) return -1; return pLayer->GetState(); } extern "C" __declspec(dllexport) void FindAddLayer(CSigmaView* pView, LPCTSTR layerName, bool doActive) { CXy* pxy = pView->m_pDoc->m_pXy; CLayer* pLayer = pxy->FindLayer(layerName); if (pLayer != nullptr) { if (doActive == TRUE) { pxy->SetCurrentLayer(pLayer); } return; } CString strCurrentLayerName = pxy->GetCurrentLayer()->GetPathName(); pLayer = pxy->FindAddLayer(layerName); if (pLayer == NULL) return; if (doActive == TRUE) { pxy->SetCurrentLayer(pLayer); } pView->m_pDoc->SetActionItem(new CActionLayerAddItem(pView->m_pDoc, pLayer, strCurrentLayerName)); } extern "C" __declspec(dllexport) void XyDeleteLayer(CXy *pxy, const wchar_t** layers, int count, bool bIncludeSublayer = false) { //pxy->RemoveLayer(layers, bIncludeSublayer); for (int i = 0; i < count; i++) { CString name(layers[i]); pxy->RemoveLayer(name, bIncludeSublayer); } } /** * 删除图元 * * \param pView 视图对象 * \param layers 图层路径 * \param length 图层路径数量 * \param bIncludeSublayer 是否连带子层一起删除 */ extern "C" __declspec(dllexport) void DeleteLayer(CSigmaView* pView, wchar_t** layers, int length, bool bIncludeSublayer = FALSE) { CXy* pxy = pView->m_pDoc->m_pXy; NBase::CPositionList elemList; CPtrList layerList; if (bIncludeSublayer == FALSE) { for (int i = 0; i < length; i++) { CString name; name = layers[i]; CLayer* pLayer = pxy->FindLayer(name, bIncludeSublayer); if (pLayer) { layerList.AddTail(pLayer); pxy->GetElement(pLayer->GetPathName(), elemList, bIncludeSublayer); } } } else { for (int i = 0; i < length; i++) { CString name; name = layers[i]; pxy->FindLayers(name, layerList, bIncludeSublayer);// bIncludeSublayer } POSITION pos = layerList.GetHeadPosition(); while (pos != nullptr) { CLayer* pLayer = (CLayer*)layerList.GetNext(pos); pxy->GetElement(pLayer->GetPathName(), elemList, TRUE); } } // 让我来告诉你为什么要除重!!! // 情况1:即不包括子层,上面传递进来的路径本身就有可能重复 // 那我们能不能通过字符串来除重?答案是,可以,但是很麻烦,你得考虑字符串左右两边带空格的情况,还得考虑带或不带 class 的情况 // 情况2:带子层一起删除,有可能传递进来的图层包含父子层的关系 // 如果不除重,后面的代码 CActionLayerDeleteItem 里面会重复存储,然后 delete 时出现 double free,进而导致程序崩溃 // CPtrList newLayerList; NBase::CPositionList newElemList; UniquePtrList(layerList, newLayerList); UniquePositionList(elemList, newElemList); CSigmaDoc* pDoc = pView->m_pDoc; if (pDoc != NULL) { pDoc->SetActionItem(new CActionLayerDeleteItem(pDoc, newElemList, newLayerList)); // pDoc->Modified(); } // 注意!如果当前图层被删除了,需要重新设置当前图层,话说,这个代码不应该在这里面吧,应该在 CXy 里面 CLayer* pLayer = pxy->GetCurrentLayer(); if (newLayerList.Find(pLayer)) { if (pxy->GetClassList()->GetLayerCount() == 0) { if (pxy->GetClassList()->GetCount() == 0) pxy->InitLayerClass(); else pxy->GetClassList()->GetHead()->FindAdd("0"); } pxy->SetCurrentLayer(pxy->GetClassList()->GetHead()->GetHead()); } } //extern "C" __declspec(dllexport) //bool ClearAll(CSigmaView* pView, bool needUndo) { // CXy* pxy = pView->m_pDoc->m_pXy; // // POSITION posClass, posLayer; // CLayerList* pLayer; // CClassList* pClass = pxy->GetClassList(); // posClass = pClass->GetHeadPosition(); // // vector layers; // //wchar_t** layerNames = new wchar_t // while (posClass) // { // pLayer = pClass->GetNext(posClass); // posLayer = pLayer->GetHeadPosition(); // while (posLayer) // { // //CString name = pLayer->GetPathName(posLayer); // CLayer* pLayerCurrent = pLayer->GetNext(posLayer); // layers.push_back(pLayerCurrent); // //CString strLayerName = pLayerCurrent->GetPathName(); // } // } // if (needUndo) // { // 需要缓存进行撤销重做 // int nLayerCount = layers.size(); // wchar_t** strArray = new wchar_t*[nLayerCount]; // // // 分配内存并复制字符串 // for (int i = 0; i < nLayerCount; ++i) { // CString strLayerName = layers[i]->GetPathName(); // int len = MultiByteToWideChar(CP_ACP, 0, strLayerName, -1, NULL, 0); // 计算宽字符长度 // strArray[i] = new wchar_t[len]; // MultiByteToWideChar(CP_ACP, 0, strLayerName, -1, strArray[i], len); // 进行转换 // } // DeleteLayer(pView, strArray, nLayerCount, true); // return true; // } // else { // pxy->RemoveAllData(); // pxy->RemoveAllLayer(); // pxy->RemoveAllLegend(); // } // return true; //} extern "C" __declspec(dllexport) void LayerRename(CSigmaView* pView, LPCTSTR oldName, LPCTSTR newName) { CXy* pxy = pView->m_pDoc->m_pXy; //修改层名 if (pxy->GetClassList()->ReplaceLayer(oldName, newName) > 0) { pView->m_pDoc->SetActionItem(new CActionLayerRenameItem(pView->m_pDoc , oldName, newName)); } } extern "C" __declspec(dllexport) bool DeleteLayerEmpty(CSigmaView* pView) { CXy* pxy = pView->m_pDoc->m_pXy; CPtrList layerList; int rt = pxy->ClearLayerNoneData(&layerList); if (layerList.GetCount() > 0) { // pDoc->SetModifiedFlag(); NBase::CPositionList list; pView->m_pDoc->SetActionItem(new CActionLayerDeleteItem(pView->m_pDoc, list, layerList)); } return rt; } extern "C" __declspec(dllexport) BOOL XyGetLayerStyleData(CXy* pxy, LPCTSTR layerName, BYTE*& buffCurve, int& lenCurve, BYTE*& buffPoint, int& lenPoint) { CLayer* pLayer = pxy->FindAddLayer(layerName); if (pLayer == NULL) return FALSE; //BYTE* dataCurve; if (pLayer->HowToViewCurve == NULL) { lenCurve = 0; } else { pLayer->HowToViewCurve->WriteMemory(buffCurve, lenCurve, 3); } if (pLayer->HowToViewPoint == NULL) { lenPoint = 0; } else { pLayer->HowToViewPoint->WriteMemory(buffPoint, lenPoint, 3); } return TRUE; } extern "C" __declspec(dllexport) BOOL GetLayerStyleData(CSigmaView* pView, LPCTSTR layerName, BYTE*& buffCurve, int& lenCurve, BYTE*& buffPoint, int& lenPoint) { CXy* pxy = pView->m_pDoc->m_pXy; CLayer* pLayer = pxy->FindAddLayer(layerName); if (pLayer == NULL) return FALSE; //BYTE* dataCurve; if (pLayer->HowToViewCurve == NULL) { lenCurve = 0; } else { pLayer->HowToViewCurve->WriteMemory(buffCurve, lenCurve, 3); } if (pLayer->HowToViewPoint == NULL) { lenPoint = 0; } else { pLayer->HowToViewPoint->WriteMemory(buffPoint, lenPoint, 3); } return TRUE; } extern "C" __declspec(dllexport) BOOL RemoveCurveStyle(CSigmaView* pView, LPCTSTR layerName, int index) { CXy* pxy = pView->m_pDoc->m_pXy; CLayer* pLayer = pxy->FindAddLayer(layerName); if (pLayer == NULL) return FALSE; if (pLayer->HowToViewCurve == NULL) { return FALSE; } //为了修饰的Redo/Undo CActionEmbellishItem *pActionItem = new CActionEmbellishItem(pView->m_pDoc, ActionTypeLayerEmbellishCurveDelete, pLayer); pActionItem->SetOldHowToView(pLayer); // 备份老修饰 CHowToViewCurve* pHW = pLayer->HowToViewCurve; pHW->RemoveAt(index); if (pHW->GetCount() == 0) { delete pLayer->HowToViewCurve; pLayer->HowToViewCurve = NULL; } pActionItem->SetNewHowToView(pLayer); pView->m_pDoc->SetActionItem(pActionItem); return TRUE; } extern "C" __declspec(dllexport) BOOL RemovePointStyle(CSigmaView* pView, LPCTSTR layerName) { CXy* pxy = pView->m_pDoc->m_pXy; CLayer* pLayer = pxy->FindAddLayer(layerName); if (pLayer == NULL) return FALSE; if (pLayer->HowToViewPoint == NULL) { return FALSE; } //为了修饰的Redo/Undo CActionEmbellishItem *pActionItem = new CActionEmbellishItem(pView->m_pDoc, ActionTypeLayerEmbellishPointDelete, pLayer); pActionItem->SetOldHowToView(pLayer); // 备份老修饰 delete pLayer->HowToViewPoint; pLayer->HowToViewPoint = nullptr; pActionItem->SetNewHowToView(pLayer); pView->m_pDoc->SetActionItem(pActionItem); return TRUE; } extern "C" __declspec(dllexport) BOOL XySetLayerHowtoViewPoint(CXy* pXy, LPCTSTR layerName, BYTE* buffCurve, int bufLen, bool replace) { CLayer* pLayer = pXy->FindAddLayer(layerName); if (pLayer == nullptr) return FALSE; if (replace == FALSE) { if (pLayer->HowToViewPoint != nullptr) { return TRUE; } } if (pLayer->HowToViewPoint == NULL) { pLayer->HowToViewPoint = new CHowToViewPoint(); } CHowToViewPoint htp; BOOL bSuccess = htp.ReadMemory(buffCurve, bufLen, 3); if (bSuccess == FALSE) { return FALSE; } *(pLayer->HowToViewPoint) = htp; return TRUE; } extern "C" __declspec(dllexport) BOOL SetLayerHowtoViewPoint(CSigmaView* pView, LPCTSTR layerName, BYTE* buffCurve, int bufLen, bool replace) { CXy* pxy = pView->m_pDoc->m_pXy; CLayer* pLayer = pxy->FindAddLayer(layerName); if (pLayer == NULL) return FALSE; if (pLayer->HowToViewPoint != nullptr && replace == false) { return false; } CHowToViewPoint htp; BOOL bSuccess = htp.ReadMemory(buffCurve, bufLen, 3); if (bSuccess == FALSE) { return FALSE; } //为了修饰的Redo/Undo CActionEmbellishItem *pActionItem = new CActionEmbellishItem(pView->m_pDoc, ActionTypeLayerEmbellishPointAdd, pLayer); pActionItem->SetOldHowToView(pLayer); // 备份老修饰 if (pLayer->HowToViewPoint == NULL) { pLayer->HowToViewPoint = new CHowToViewPoint(); } *(pLayer->HowToViewPoint) = htp; // 查找所有组合并设置层修改 CPtrList* plist = pxy->GetValueList(); POSITION pos; COne* pOne; pos = plist->GetHeadPosition(); while (pos) { pOne = (COne*)plist->GetNext(pos); if (pOne->GetType() != DOUBLEFOX_BLOCK)continue; CInsertBlock* pBlock = ((CInsertBlock*)pOne->value); CXy* pXyBlock = (CXy*)pBlock->GetXy(); CLayer* pLayerBlock = pXyBlock->FindLayer(layerName); if (pLayerBlock != nullptr) { CHowToViewPoint* hvpBlock = NULL; if (pLayer->HowToViewPoint) { hvpBlock = new CHowToViewPoint; *hvpBlock = *(pLayer->HowToViewPoint); } pLayerBlock->SetHowToViewPoint(hvpBlock); } } pActionItem->SetNewHowToView(pLayer); pView->m_pDoc->SetActionItem(pActionItem); return TRUE; } extern "C" __declspec(dllexport) BOOL CreateLayerPointStyle(CSigmaView * pView, LPCTSTR layerName, BYTE * buffPoint, int bufLen) { return SetLayerHowtoViewPoint(pView, layerName, buffPoint, bufLen, true); } extern "C" __declspec(dllexport) bool XyCreateLayerCurveStyle(CXy * pxy, LPCTSTR layerName, int type, BYTE * buffCurve, int bufLen) { CLayer* pLayer = pxy->FindAddLayer(layerName); if (pLayer == NULL) return FALSE; ////为了修饰的Redo/Undo //CActionEmbellishItem *pActionItem = new CActionEmbellishItem(pView->m_pDoc, ActionTypeLayerEmbellishCurveAdd, pLayer); //pActionItem->SetOldHowToView(pLayer); // 备份老修饰 if (pLayer->HowToViewCurve == NULL) { pLayer->HowToViewCurve = new CHowToViewCurve(); } CHowToViewCurve* pHWCOld = pLayer->HowToViewCurve; pHWCOld->Empty(); switch (type) { case CurveArrowHead: case CurveArrowTail: pHWCOld->Add(new CCurveArrow()); break; case CurveProperties: pHWCOld->Add(new CCurveProperties()); break; case CurveLocate: pHWCOld->Add(new CCurveLocate()); break; case CurveScale: pHWCOld->Add(new CCurveScale()); break; //case CurveName: case CurveNameHead: case CurveNameTail: pHWCOld->Add(new CCurveName()); break; case CurveTwoMark: pHWCOld->Add(new CCurveTwoMark()); break; case CurveRgn: pHWCOld->Add(new CCurveRgn()); break; case CurveInName: pHWCOld->Add(new CCurveInName()); break; case CurveInNameAny: pHWCOld->Add(new CCurveInNameAny()); break; case CurveEffect: pHWCOld->Add(new CCurveEffect()); break; case CurveCenterName: pHWCOld->Add(new CCurveCenterName()); break; } bool bSuccess = pHWCOld->SetAt(pHWCOld->GetCount() - 1, buffCurve, bufLen, 3) != NULL; return bSuccess; } extern "C" __declspec(dllexport) bool CreateLayerCurveStyle(CSigmaView* pView, LPCTSTR layerName, int type, BYTE * buffCurve, int bufLen) { CXy* pxy = pView->m_pDoc->m_pXy; CLayer* pLayer = pxy->FindAddLayer(layerName); if (pLayer == NULL) return FALSE; //为了修饰的Redo/Undo CActionEmbellishItem *pActionItem = new CActionEmbellishItem(pView->m_pDoc, ActionTypeLayerEmbellishCurveAdd, pLayer); pActionItem->SetOldHowToView(pLayer); // 备份老修饰 XyCreateLayerCurveStyle(pxy, layerName, type, buffCurve, bufLen); // 查找所有组合并设置层修改 CPtrList* plist = pxy->GetValueList(); POSITION pos; COne* pOne; pos = plist->GetHeadPosition(); while (pos) { pOne = (COne*)plist->GetNext(pos); if (pOne->GetType() != DOUBLEFOX_BLOCK)continue; CInsertBlock* pBlock = ((CInsertBlock*)pOne->value); CXy* pXyBlock = (CXy*)pBlock->GetXy(); CLayer* pLayerBlock = pXyBlock->FindLayer(layerName); if (pLayerBlock != nullptr) { CHowToViewCurve* hvcBlock = nullptr; if (pLayer->HowToViewCurve) { hvcBlock = new CHowToViewCurve; *hvcBlock = *(pLayer->HowToViewCurve); } pLayerBlock->SetHowToViewCurve(hvcBlock); } } pActionItem->SetNewHowToView(pLayer); pView->m_pDoc->SetActionItem(pActionItem); return true; } extern "C" __declspec(dllexport) bool AddLayerCurveStyle(CSigmaView* pView, LPCTSTR layerName, int type, BYTE * buffCurve, int bufLen) { CXy* pxy = pView->m_pDoc->m_pXy; CLayer* pLayer = pxy->FindAddLayer(layerName); if (pLayer == NULL) return FALSE; if (pLayer->HowToViewCurve == NULL) { return CreateLayerCurveStyle(pView, layerName, type, buffCurve, bufLen); } //为了修饰的Redo/Undo CActionEmbellishItem *pActionItem = new CActionEmbellishItem(pView->m_pDoc, ActionTypeLayerEmbellishCurveAdd, pLayer); pActionItem->SetOldHowToView(pLayer); // 备份老修饰 CHowToViewCurve* pHWCOld = pLayer->HowToViewCurve; switch (type) { case CurveArrowHead: case CurveArrowTail: pHWCOld->Add(new CCurveArrow(type)); break; case CurveProperties: pHWCOld->Add(new CCurveProperties()); break; case CurveLocate: pHWCOld->Add(new CCurveLocate()); break; case CurveScale: pHWCOld->Add(new CCurveScale()); break; case CurveNameHead: case CurveNameTail: pHWCOld->Add(new CCurveName()); break; case CurveTwoMark: pHWCOld->Add(new CCurveTwoMark()); break; case CurveRgn: pHWCOld->Add(new CCurveRgn()); break; case CurveInName: pHWCOld->Add(new CCurveInName()); break; case CurveInNameAny: pHWCOld->Add(new CCurveInNameAny()); break; case CurveEffect: pHWCOld->Add(new CCurveEffect()); break; case CurveCenterName: pHWCOld->Add(new CCurveCenterName()); break; } bool bSuccess = pHWCOld->SetAt(pHWCOld->GetCount() - 1, buffCurve, bufLen, 3) != NULL; // 查找所有组合并设置层修改 CPtrList* plist = pxy->GetValueList(); POSITION pos; COne* pOne; pos = plist->GetHeadPosition(); while (pos) { pOne = (COne*)plist->GetNext(pos); if (pOne->GetType() != DOUBLEFOX_BLOCK)continue; CInsertBlock* pBlock = ((CInsertBlock*)pOne->value); CXy* pXyBlock = (CXy*)pBlock->GetXy(); CLayer* pLayerBlock = pXyBlock->FindLayer(layerName); if (pLayerBlock != nullptr) { CHowToViewCurve* hvcBlock = nullptr; if (pHWCOld) { hvcBlock = new CHowToViewCurve; *hvcBlock = *(pHWCOld); } pLayerBlock->SetHowToViewCurve(hvcBlock); } } pActionItem->SetNewHowToView(pLayer); pView->m_pDoc->SetActionItem(pActionItem); return bSuccess; } extern "C" __declspec(dllexport) BOOL SetLayerHowtoViewCurve(CSigmaView* pView, LPCTSTR layerName, BYTE* buffCurve, int bufLen, int index) { CXy* pxy = pView->m_pDoc->m_pXy; CLayer* pLayer = pxy->FindAddLayer(layerName); if (pLayer == NULL) return FALSE; CHowToViewCurve* pHWCOld = pLayer->HowToViewCurve; if (pHWCOld == NULL) { return FALSE; } if (pHWCOld->GetCount() <= index) { return FALSE; } //为了修饰的Redo/Undo CActionEmbellishItem *pActionItem = new CActionEmbellishItem(pView->m_pDoc, ActionTypeLayerEmbellishCurveAdd, pLayer); pActionItem->SetOldHowToView(pLayer); // 备份老修饰 pHWCOld->SetAt(index, buffCurve, bufLen, 3); // 查找所有组合并设置层修改 CPtrList* plist = pxy->GetValueList(); POSITION pos; COne* pOne; pos = plist->GetHeadPosition(); while (pos) { pOne = (COne*)plist->GetNext(pos); if (pOne->GetType() != DOUBLEFOX_BLOCK)continue; CInsertBlock* pBlock = ((CInsertBlock*)pOne->value); CXy* pXyBlock = (CXy*)pBlock->GetXy(); CLayer* pLayerBlock = pXyBlock->FindLayer(layerName); if (pLayerBlock != nullptr) { CHowToViewCurve* hvcBlock = nullptr; if (pHWCOld) { hvcBlock = new CHowToViewCurve; *hvcBlock = *(pHWCOld); } pLayerBlock->SetHowToViewCurve(hvcBlock); } } pActionItem->SetNewHowToView(pLayer); pView->m_pDoc->SetActionItem(pActionItem); return TRUE; } extern "C" __declspec(dllexport) BOOL XySetLayerHowtoViewCurve(CXy* pxy, LPCTSTR layerName, BYTE* buffCurve, int bufLen, int index) { CLayer* pLayer = pxy->FindAddLayer(layerName); if (pLayer == NULL) return FALSE; CHowToViewCurve* pHWCOld = pLayer->HowToViewCurve; if (pHWCOld == NULL) { return FALSE; } if (pHWCOld->GetCount() <= index) { return FALSE; } pHWCOld->SetAt(index, buffCurve, bufLen, 3); return TRUE; } extern "C" __declspec(dllexport) BOOL SetLayerMoveUpCurveStyle(CSigmaView * pView, LPCTSTR layerName, int nIndex) { CXy* pxy = pView->m_pDoc->m_pXy; CLayer* pLayer = pxy->FindAddLayer(layerName); if (pLayer == NULL) return FALSE; if (pLayer->HowToViewCurve == NULL) { return FALSE; } //为了修饰的Redo/Undo CActionEmbellishItem *pActionItem = new CActionEmbellishItem(pView->m_pDoc, ActionTypeLayerEmbellishCurveMoveUp, pLayer); pActionItem->SetOldHowToView(pLayer); // 备份老修饰 CHowToViewCurve* pHW = pLayer->HowToViewCurve; BOOL bSuccess = pHW->MoveUp(nIndex); pActionItem->SetNewHowToView(pLayer); pView->m_pDoc->SetActionItem(pActionItem); return bSuccess; } extern "C" __declspec(dllexport) BOOL SetLayerMoveDownCurveStyle(CSigmaView * pView, LPCTSTR layerName, int nIndex) { CXy* pxy = pView->m_pDoc->m_pXy; CLayer* pLayer = pxy->FindAddLayer(layerName); if (pLayer == NULL) return FALSE; if (pLayer->HowToViewCurve == NULL) { return FALSE; } //为了修饰的Redo/Undo CActionEmbellishItem *pActionItem = new CActionEmbellishItem(pView->m_pDoc, ActionTypeLayerEmbellishCurveMoveDown, pLayer); pActionItem->SetOldHowToView(pLayer); // 备份老修饰 CHowToViewCurve* pHW = pLayer->HowToViewCurve; BOOL bSuccess = pHW->MoveDown(nIndex); pActionItem->SetNewHowToView(pLayer); pView->m_pDoc->SetActionItem(pActionItem); return bSuccess; } extern "C" __declspec(dllexport) BOOL ExportImageFile(CSigmaView * pView, LPCTSTR outputFile, int width, int height, int bpp) { CSize size(width, height); CItemExportFile item(pView->m_pDoc); return item.Export(outputFile, size, bpp); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// extern "C" __declspec(dllexport) void AddWell(LPCTSTR wellName, double locationX, double locationY) { //if (pSectionDoc == nullptr) //{ // pSectionDoc = new CSectionDoc(); //} //pSectionDoc->AddWell(wellName, locationX, locationY); } extern "C" __declspec(dllexport) void SetWellStratiUnits(LPCTSTR wellName, int count , LPCTSTR* stratiNames, double* tops, double* bottoms, LPCTSTR* unitNames) { //pSectionDoc->SetWellStratiUnits(wellName, count, stratiNames, tops, bottoms, unitNames); } extern "C" __declspec(dllexport) int DrawBend(CSigmaView* pView, LPCTSTR leftWell, LPCTSTR leftStrati, LPCTSTR rightWell, LPCTSTR rightStrati) { //CPointList lstPt; //// 左井层位顶坐标 //CRect8 leftRect = pSectionDoc->GetStratiRect(leftWell, leftStrati); //CRect8 rightRect = pSectionDoc->GetStratiRect(rightWell, rightStrati); //dfPoint ptLeftTop; ptLeftTop.Create(leftRect.right, leftRect.top,0); //dfPoint ptRightTop; ptRightTop.Create(rightRect.left, rightRect.top,0); //dfPoint ptRightBottom; ptRightBottom.Create(rightRect.left, rightRect.bottom, 0); //dfPoint ptLeftBottom; ptLeftBottom.Create(leftRect.right, leftRect.bottom, 0); //lstPt.AddTail(ptLeftTop); //lstPt.AddTail(ptRightTop); //lstPt.AddTail(ptRightBottom); //lstPt.AddTail(ptLeftBottom); //CEntityBend* pBend = pSectionDoc->FindBend(leftWell, leftStrati, rightWell, rightStrati); //if (pBend == nullptr) //{ // pBend = new CEntityBend(); // pBend->SetName(leftWell, leftStrati, rightWell, rightStrati); // pBend->SetData(lstPt); // pSectionDoc->AddBend(pBend); //} //pBend->Draw(pView->m_pDC, RGB(205, 0, 0)); // ////CDrawBend* pDrawBend = new CDrawBend(); ////pDrawBend->Draw(pView->m_pDC, lstPt, RGB(255, 0, 0)); return 0; } extern "C" __declspec(dllexport) void SetItem(CSigmaView* pView, int itemType) { pView->SetItem(itemType); } extern "C" __declspec(dllexport) int MouseSelect(CSigmaView* pView, int mouseX, int mouseY) { //pSectionDoc->SelectBend(pView->m_pDC, mouseX, mouseY); //GSD_Select(pView->m_pDoc, mouseX, mouseY); return 0; } extern "C" __declspec(dllexport) bool DrawMem(CSigmaView* pView) { pView->OnDrawMem(); return true; } extern "C" __declspec(dllexport) bool DrawDC(CSigmaView* pView) { return pView->OnDrawDC(); } extern "C" __declspec(dllexport) BOOL OpenDocument(CSigmaView* pView, LPCTSTR lpszFileName, BOOL bMergeFile) { return pView->OpenFile(lpszFileName, bMergeFile); } extern "C" __declspec(dllexport) BOOL OpenXy(CSigmaView* pView, CXy* pXy, BOOL bMergeFile) { return pView->OpenXy(pXy, bMergeFile); } extern "C" __declspec(dllexport) void EnableMeshPackage(CSigmaView* pView, BOOL isEnable, BOOL force) { pView->EnableMeshPackage(isEnable, force); } extern "C" __declspec(dllexport) void SetMainMeshId3D(CSigmaView* pView, int64_t id) { pView->SetMainMeshId3D(id); } extern "C" __declspec(dllexport) int64_t GetMainMeshId3D(CSigmaView* pView) { return pView->GetMainMeshId3D(); } extern "C" __declspec(dllexport) int64_t GetMainMeshIdByMesh3D(CSigmaView* pView, void* pMesh) { if (pMesh == nullptr) { return -1; } return ((KevVtkMeshData*)pMesh)->id; } extern "C" __declspec(dllexport) void* GetMainMeshByMeshId3D(CSigmaView* pView, int64_t id) { CXy* pXy = pView->m_pDoc->m_pXy; COne* pOne = pXy->GetOneById(id); if (pOne->GetType() == DOUBLEFOX_MESH) { KevVtkMeshData* pKevVtkMeshData = new KevVtkMeshData; CMesh* pMesh = (CMesh*)pOne->GetValue(); double zmin, zmax; pMesh->GetM(zmin, zmax); pKevVtkMeshData->m_zMin = zmin; pKevVtkMeshData->m_zMax = zmax; double x0, y0; pMesh->GetOrg(x0, y0); pKevVtkMeshData->x0 = x0; pKevVtkMeshData->y0 = y0; double dx, dy; pMesh->GetDelt(dx, dy); pKevVtkMeshData->dx = dx; pKevVtkMeshData->dy = dy; CGrid* pGrid = pMesh->GetMesh(); long numX = pGrid->xnum(); long numY = pGrid->ynum(); pKevVtkMeshData->numX = numX; pKevVtkMeshData->numY = numY; CDimension3D* pdfg = pMesh->GetDfg(); if (pdfg == NULL) return nullptr; pKevVtkMeshData->num = pdfg->num; pKevVtkMeshData->P0 = pdfg->P0; pKevVtkMeshData->delt = pdfg->delt; double* pShadow = new double[pdfg->total]; std::memcpy(pShadow, pdfg->u, pdfg->total * sizeof(double)); pKevVtkMeshData->shadow_u = pShadow; pKevVtkMeshData->origin_u = pdfg->u; pKevVtkMeshData->range = pdfg->range; pKevVtkMeshData->n = pdfg->n; CColorBase& color = pMesh->color; for (int i = 0; i < color.sizeColor(); i++) { CColorItem& item = color.GetColorItem(i); KevVtkColorItem* pColorItem = new KevVtkColorItem(); pColorItem->z = item.z; pColorItem->color[0] = item.color.rgbRed; pColorItem->color[1] = item.color.rgbGreen; pColorItem->color[2] = item.color.rgbBlue; pColorItem->color[3] = item.color.rgbReserved; pColorItem->gradient = item.m_bContinue; pKevVtkMeshData->m_colorList.push_back(pColorItem); } pKevVtkMeshData->id = pMesh->GetId(); return pKevVtkMeshData; } else { return nullptr; } } extern "C" __declspec(dllexport) void GetLayerByMainMesh3D(CSigmaView* pView, void* pMesh, wchar_t** layer) { if (pMesh == nullptr) { CString strLayer; int len = sizeof(wchar_t) * (strLayer.GetLength() + 1); *layer = new wchar_t[len]; memset(*layer, 0, len); wcscpy_s(*layer, len, CT2CW(strLayer)); return; } else { CString strLayer(((KevVtkMeshData*)pMesh)->m_layerName.c_str()); int len = sizeof(wchar_t) * (strLayer.GetLength() + 1); *layer = new wchar_t[len]; memset(*layer, 0, len); wcscpy_s(*layer, len, CT2CW(strLayer)); return; } } extern "C" __declspec(dllexport) void* GetMainMeshByLayer3D(CSigmaView* pView, LPCTSTR layer) { CXy* pXy = pView->m_pDoc->GetDraw(); if (pXy == nullptr) return nullptr; NBase::CPositionList elements; //获取图层元素,不包含子图层 pXy->GetElement(layer, elements, false); POSITION p = nullptr; COne* pOne = nullptr; POSITION pos; pos = elements.GetHeadPosition(); KevVtkMeshData* pKevVtkMesh = nullptr; while (pos) { p = elements.GetNext(pos); pOne = (COne*)pXy->GetValueList()->GetAt(p); int type = pOne->GetType(); switch (type) { case DOUBLEFOX_MESH: { pKevVtkMesh = new KevVtkMeshData; CMesh* pMesh = (CMesh*)pOne->GetValue(); double zmin, zmax; pMesh->GetM(zmin, zmax); pKevVtkMesh->m_zMin = zmin; pKevVtkMesh->m_zMax = zmax; double x0, y0; pMesh->GetOrg(x0, y0); pKevVtkMesh->x0 = x0; pKevVtkMesh->y0 = y0; double dx, dy; pMesh->GetDelt(dx, dy); pKevVtkMesh->dx = dx; pKevVtkMesh->dy = dy; CGrid* pGrid = pMesh->GetMesh(); long numX = pGrid->xnum(); long numY = pGrid->ynum(); pKevVtkMesh->numX = numX; pKevVtkMesh->numY = numY; CDimension3D* pdfg = pMesh->GetDfg(); if (pdfg == NULL) return nullptr; pKevVtkMesh->num = pdfg->num; pKevVtkMesh->P0 = pdfg->P0; pKevVtkMesh->delt = pdfg->delt; double* pShadow = new double[pdfg->total]; std::memcpy(pShadow, pdfg->u, pdfg->total * sizeof(double)); pKevVtkMesh->shadow_u = pShadow; pKevVtkMesh->origin_u = pdfg->u; pKevVtkMesh->range = pdfg->range; pKevVtkMesh->n = pdfg->n; pKevVtkMesh->m_layerName = layer; pKevVtkMesh->id = pMesh->GetId(); CColorBase& color = pMesh->color; for (int i = 0; i < color.sizeColor(); i++) { CColorItem& item = color.GetColorItem(i); KevVtkColorItem* pColorItem = new KevVtkColorItem(); pColorItem->z = item.z; pColorItem->color[0] = item.color.rgbRed; pColorItem->color[1] = item.color.rgbGreen; pColorItem->color[2] = item.color.rgbBlue; pColorItem->color[3] = item.color.rgbReserved; pColorItem->gradient = item.m_bContinue; pKevVtkMesh->m_colorList.push_back(pColorItem); } return pKevVtkMesh; } break; default: break; } } return pKevVtkMesh; } extern "C" __declspec(dllexport) void SetFaultLayer(CSigmaView* pView, LPCTSTR faultLayer) { pView->SetFaultLayer(faultLayer); } extern "C" __declspec(dllexport) void GetFaultLayer(CSigmaView* pView, wchar_t** faultLayer) { CString strFaultLayer = pView->GetFaultLayer(); int len = sizeof(wchar_t)*(strFaultLayer.GetLength() + 1); *faultLayer = new wchar_t[len]; memset(*faultLayer, 0, len); wcscpy_s(*faultLayer, len, CT2CW(strFaultLayer)); } extern "C" __declspec(dllexport) void SetBorderLayer(CSigmaView* pView, LPCTSTR faultLayer) { pView->SetBorderLayer(faultLayer); } extern "C" __declspec(dllexport) void GetBorderLayer(CSigmaView* pView, wchar_t** borderLayer) { CString strLayer = pView->GetBorderLayer(); int len = sizeof(wchar_t) * (strLayer.GetLength() + 1); *borderLayer = new wchar_t[len]; memset(*borderLayer, 0, len); wcscpy_s(*borderLayer, len, CT2CW(strLayer)); } extern "C" __declspec(dllexport) void SetFaultLayer3D(CSigmaView* pView, LPCTSTR faultLayer) { pView->SetFaultLayer3D(faultLayer); } extern "C" __declspec(dllexport) void GetFaultLayer3D(CSigmaView* pView, wchar_t** faultLayer) { CString strFaultLayer = pView->GetFaultLayer3D(); int len = sizeof(wchar_t) * (strFaultLayer.GetLength() + 1); *faultLayer = new wchar_t[len]; memset(*faultLayer, 0, len); wcscpy_s(*faultLayer, len, CT2CW(strFaultLayer)); } extern "C" __declspec(dllexport) void SetBorderLayer3D(CSigmaView* pView, LPCTSTR faultLayer) { pView->SetBorderLayer3D(faultLayer); } extern "C" __declspec(dllexport) void GetBorderLayer3D(CSigmaView* pView, wchar_t** borderLayer) { CString strLayer = pView->GetBorderLayer3D(); int len = sizeof(wchar_t)*(strLayer.GetLength() + 1); *borderLayer = new wchar_t[len]; memset(*borderLayer, 0, len); wcscpy_s(*borderLayer, len, CT2CW(strLayer)); } extern "C" __declspec(dllexport) void SetWellLayer3D(CSigmaView* pView, LPCTSTR wellLayer) { pView->SetWellLayer3D(wellLayer); } extern "C" __declspec(dllexport) void GetWellLayer3D(CSigmaView* pView, wchar_t** wellLayer) { CString strLayer = pView->GetWellLayer3D(); int len = sizeof(wchar_t)*(strLayer.GetLength() + 1); *wellLayer = new wchar_t[len]; memset(*wellLayer, 0, len); wcscpy_s(*wellLayer, len, CT2CW(strLayer)); } extern "C" __declspec(dllexport) void SetMainMeshLayer3D(CSigmaView* pView, LPCTSTR layer) { pView->SetMainMeshLayer3D(layer); } extern "C" __declspec(dllexport) void GetMainMeshLayer3D(CSigmaView* pView, wchar_t** wellLayer) { CString strLayer = pView->GetMainMeshLayer3D(); int len = sizeof(wchar_t) * (strLayer.GetLength() + 1); *wellLayer = new wchar_t[len]; memset(*wellLayer, 0, len); wcscpy_s(*wellLayer, len, CT2CW(strLayer)); } extern "C" __declspec(dllexport) BOOL ReloadFile(CSigmaView* pView) { return pView->ReloadFile(); } extern "C" __declspec(dllexport) BOOL NewDocument(CSigmaView * pView, LPCTSTR lpszFileName) { return pView->CreateNew(lpszFileName); } extern "C" __declspec(dllexport) BOOL SaveDocument(CSigmaView * pView, LPCTSTR fileName) { if (pView == NULL) return false; return pView->m_pDoc->SaveFile(fileName); } extern "C" __declspec(dllexport) BOOL SavePdfDocument(CSigmaView* pView, LPCTSTR fileName, double leftMargin, double rightMargin, double topMargin, double bottomMargin, int paperSizeType, int pdfAHType, int pdfPapertDirectionType) { if (pView == NULL) return false; return pView->m_pDoc->SaveFile(fileName, leftMargin, rightMargin, topMargin, bottomMargin, paperSizeType, pdfAHType, pdfPapertDirectionType); } extern "C" __declspec(dllexport) void SaveActionPosition(CSigmaView * pView) { pView->m_pDoc->SaveActionPosition(); } extern "C" __declspec(dllexport) void SetDefaultMeshColorTemplate(int values[], double Zs[], int itemsCount) { TTypeSet* colorItems = &(CColorBase::GetMeshDefault()); colorItems->erase(); CColorItem ci; for (int i = 0; i < itemsCount; i++) { ci.SetColor(values[i * 3], values[i * 3 + 1], values[i * 3 + 2]); ci.z = Zs[i]; colorItems->add(ci); } return; } //函数功能文档是否被修改 //返回值:-1--出现异常 0--未修改 1--已修改 extern "C" __declspec(dllexport) int Sigma_IsDocumentModified(CSigmaView * pView) { if (pView == NULL) return -1; if (pView->m_pDoc == NULL) return -1; if (pView->m_pDoc->IsModified()) return 1; return 0; } extern "C" __declspec(dllexport) void Sigma_SetDocumentModified(CSigmaView * pView, BOOL modified) { if (pView == NULL || pView->m_pDoc == NULL) return; pView->m_pDoc->Modified(modified); } //0--左下箭头 1--垂直箭头 2--右下箭头 3--水平箭头 //4--旋转箭头 5--水平剪切箭头 6--垂直剪切箭头 7--平移箭头 //-1 出错 extern "C" __declspec(dllexport) int GetTrackerHandleCursorType(CSigmaView * pView, int mouseX, int mouseY) { if (pView == NULL) return -1; CItem * pItem = pView->GetItem(); if (pItem == NULL) return -1; CItemSelect * itemSelect = dynamic_cast(pItem); if (itemSelect == NULL) return -1; CPoint ptHit(mouseX, mouseY); int nHit = itemSelect->GetTracker().HitTest(ptHit); return nHit; } extern "C" __declspec(dllexport) int GeoSigma_ScaleFont(CSigmaView * pView, int bBig) { if (pView == 0) return -1; if (pView->m_pDoc == 0) return -1; bool bCtrl = ::IsKeyDown(VK_CONTROL); CItemScaleEmbellish item(pView->m_pDoc); if (bBig != 0) item.ScaleFont(bCtrl ? 1.05 : 1.25); else item.ScaleFont(bCtrl ? 0.95 : 0.8); pView->m_pDoc->Modified(); return 1; } extern "C" __declspec(dllexport) int GetCoordinateXY(CSigmaView* pView, int mouseX, int mouseY, BYTE* coordinate) { NBase::CPoint2D pt; CPoint point(mouseX, mouseY); pt = pView->m_pDoc->GetDC().GetReal(point); CString pX, pY; pX.Format(_T("%lf"), pt.x0); pY.Format(_T("%lf"), pt.y0); pX = "X:" + pX + " , Y:" + pY; int nLen = pX.GetLength(); memcpy(coordinate, pX.GetBuffer(0), nLen); return nLen; } /** * 根据屏幕两点坐标获取实际距离 * * \param pView * \param x1 * \param y1 * \param x2 * \param y2 * * \return 实际距离 */ extern "C" __declspec(dllexport) double GetRealDistance(CSigmaView * pView, int x1, int y1, int x2, int y2) { CXyDC &xyDC = pView->m_pDoc->GetDC(); double realX1 = xyDC.GetRX((long)x1); double realY1 = xyDC.GetRY((long)y1); double realX2 = xyDC.GetRX((long)x2); double realY2 = xyDC.GetRY((long)y2); double xDistance = realX2 - realX1; double yDistance = realY2 - realY1; return sqrt(xDistance * xDistance + yDistance * yDistance); } extern "C" __declspec(dllexport) void ClearAll(CSigmaView* pView, bool needUndo) { if (pView == nullptr || pView->m_pDoc == nullptr || pView->m_pDoc->m_pXy == nullptr) { TRACE("pView pView->m_pDoc pView->m_pDoc->m_pXy 都不能为 nullptr"); return; } // 清理撤消/反处理 pView->m_pDoc->GetActionManager()->ClearTarget(); // 清理当前 Item,我们必须清理掉当前 Item,不然它还会存储对应元素指针等数据,再操作时就会报错 int nItemType = pView->m_pDoc->GetItemType(); pView->m_pDoc->DeleteItem(); // 清理完后,C# 上层还处理原来的状态,于是我们还要恢复回去 pView->SetItem(nItemType); pView->m_pDoc->m_pXy->Clear(); } extern "C" __declspec(dllexport) int Sigma_HighLightGraphItem(CSigmaView * pView, int mouseX, int mouseY, HDC screenHDC) { if (pView == NULL) return -1; CDC *pDC = CDC::FromHandle(screenHDC); return pView->HighLightGraphItem(mouseX, mouseY, pDC); } extern "C" __declspec(dllexport) void Sigma_EndHighLightGraphItem(CSigmaView * pView) { if (pView == NULL) return; pView->EndHighLightGraphItem(); } //返回值:-1--出错 0--未选中图元 正整数--tipInfo字符串的长度 extern "C" __declspec(dllexport) int Sigma_GetHighLightTip(CSigmaView * pView, wchar_t ** tipInfo) { if (pView == 0 || tipInfo == 0) return -1; *tipInfo = pView->GetTipInfoString(); return (int)wcslen(*tipInfo); } extern "C" __declspec(dllexport) POSITION GetMaxPositon(CSigmaView * pView) { CXy * pXy = pView->m_pDoc->m_pXy; if (pXy == 0) { return 0; } CPtrList * values = pXy->GetValueList(); POSITION pos = values->GetHeadPosition(); POSITION maxPos = pos; while (pos) { values->GetNext(pos); if (maxPos < pos) { maxPos = pos; } } return maxPos; } extern "C" __declspec(dllexport) void SigmaLog(LPCTSTR msg) { if (bInitLog == false) { bInitLog = true; InitLog(); } spdlog::info(msg); } //extern "C" __declspec(dllexport) //void EnableCrossLine(CSigmaView * pView, bool bEnable) //{ // pView->EnableCrossLine(bEnable); //} // //extern "C" __declspec(dllexport) //bool GetCrossLineEnabledStatus(CSigmaView * pView) //{ // return pView->GetCrossLineEnabledStatus(); //} extern "C" __declspec(dllexport) int Sigma_LayerSort(CSigmaView * pView, bool enable) { if (pView == NULL) { return -1; } CXy * pXy = pView->m_pDoc->m_pXy; if (pXy == NULL) { //::AfxMessageBox("GetXY() error"); return -1; } BOOL bEnable = enable ? TRUE : FALSE; if (pXy->IsLayerSort() != bEnable) { pXy->EnableLayerSort(bEnable); pView->m_pDoc->Modified(); } return 1; //CMainFrame* pmf = (CMainFrame*)GetMainFrame(); //CDFDrawProDoc* pDoc = (CDFDrawProDoc*)pmf->GetActiveDoc(); //if (pDoc) //{ // pDoc->SetModifiedFlag(); // pDoc->Invalidate(); //} } extern "C" __declspec(dllexport) int Sigma_Fill(CSigmaView * pView, int extendLength) { if (pView == NULL) return -1; CItem * pItem = pView->GetItem(); if (pItem == NULL) return -1; CItemSolid * itemSolid = dynamic_cast(pItem); itemSolid->m_iMaxExtendLength = extendLength; if (itemSolid == NULL) return -1; itemSolid->DoSelectEnd(); return 1; } extern "C" __declspec(dllexport) int Sigma_Fill_SetStatusOfCrossPoint(CSigmaView * pView, int status) { if (status != -1 && status != 0 && status != 1) return -1; if (pView == NULL) return -1; if (pView->m_pDoc == nullptr) return -1; pView->m_pDoc->SetStatusOfCrossPoint(status); return 1; } //函数功能:填充时选择的图元是否有交点 //返回值:-1出错 0没有交点 1有交点 extern "C" __declspec(dllexport) int Sigma_Fill_GetStatusOfCrossPoint(CSigmaView * pView) { if (pView == NULL) return -1; if (pView->m_pDoc == nullptr) return -1; return pView->m_pDoc->GetStatusOfCrossPoint(); } extern "C" __declspec(dllexport) int Sigma_Fill_Link(CSigmaView * pView) { if (pView == NULL) return -1; CItem * pItem = pView->GetItem(); if (pItem == NULL) return -1; CItemSolidLink * itemSolidLink = dynamic_cast(pItem); if (itemSolidLink == NULL) return -1; itemSolidLink->DoSelectEnd(); return 1; } extern "C" __declspec(dllexport) int Sigma_Fill_Auto(CSigmaView * pView, int extendLength) { if (pView == NULL) return -1; CItem * pItem = pView->GetItem(); if (pItem == NULL) return -1; CItemSolidAuto * itemSolidAuto = dynamic_cast(pItem); itemSolidAuto->m_iMaxExtendLength = extendLength; if (itemSolidAuto == NULL) return -1; return 1; } extern "C" __declspec(dllexport) int Sigma_ZPositiveNegativeSign(CSigmaView * pView) { pView->OnProcessZFlag(); return 1; } extern "C" bool XyInsertDataBottom(CXy* pXy, BYTE* data, int dataLen, LPCTSTR newLayer); extern "C" __declspec(dllexport) bool Sigma_InsertDataBottom(CSigmaView * pView, BYTE* data, int dataLen) { CSigmaDoc *pDoc = pView->m_pDoc; CXy* pXy = pDoc->m_pXy; return XyInsertDataBottom(pXy, data, dataLen, ""); } static void InitLog() { try { //5M=1048576 * 5 //开启循环日志 日志大小为5M 日志文件数量3个 //spdlog的版本1.5.0 auto fileLogger = spdlog::rotating_logger_mt("logger", "logs/sigma.txt", 1048576 * 5, 3); //auto file_logger = spdlog::rotating_logger_mt("basic_logger", "logs/basic.txt", 1048, 3); spdlog::set_default_logger(fileLogger); } catch (const spdlog::spdlog_ex &) { //std::cout << "Log init failed: " << ex.what() << std::endl; } } int GetEncoderClsid(const wchar_t* format, CLSID* pClsid) { UINT num = 0; UINT size = 0; ImageCodecInfo* pImageCodecInfo = NULL; GetImageEncodersSize(&num, &size); if (size == 0) return -1; pImageCodecInfo = (ImageCodecInfo*)(malloc(size)); if (pImageCodecInfo == NULL) return -1; GetImageEncoders(num, size, pImageCodecInfo); for (UINT j = 0; j < num; ++j) { if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0) { *pClsid = pImageCodecInfo[j].Clsid; free(pImageCodecInfo); return j; } } free(pImageCodecInfo); return -1; } BOOL SaveAs(CDC* pDC, const wchar_t* lpszFilename) { CBitmap* pBitmap = pDC->GetCurrentBitmap(); BITMAP bmp; pBitmap->GetBitmap(&bmp); CRect rcClient = CRect(0, 0, bmp.bmWidth, bmp.bmHeight); CBitmap screenbitmap; screenbitmap.CreateCompatibleBitmap(pDC, rcClient.Width(), rcClient.Height()); CDC memDC; memDC.CreateCompatibleDC(pDC); CBitmap *pOldBitmap = memDC.SelectObject(&screenbitmap); memDC.SetStretchBltMode(HALFTONE); memDC.StretchBlt(0, 0, rcClient.Width(), rcClient.Height(), pDC, 0, 0, rcClient.Width(), rcClient.Height(), SRCCOPY); memDC.SelectObject(pOldBitmap); Bitmap bitmap((HBITMAP)screenbitmap.GetSafeHandle(), NULL); CLSID picClsid; CString sFileName(lpszFilename); CString sExt = sFileName.Right(3).MakeLower(); if (sExt == "jpg") { ULONG encoderQuality = 80; //压缩比例 EncoderParameters encoderParameters; encoderParameters.Count = 1; encoderParameters.Parameter[0].Guid = EncoderQuality; encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong; encoderParameters.Parameter[0].NumberOfValues = 1; encoderParameters.Parameter[0].Value = &encoderQuality; GetEncoderClsid(L"image/jpeg", &picClsid); bitmap.Save(lpszFilename, &picClsid, &encoderParameters); } else if (sExt == "png") { GetEncoderClsid(L"image/png", &picClsid); bitmap.Save(lpszFilename, &picClsid, NULL); } else if (sExt == "bmp") { GetEncoderClsid(L"image/bmp", &picClsid); bitmap.Save(lpszFilename, &picClsid, NULL); } else { DeleteObject(screenbitmap); memDC.DeleteDC(); return FALSE; } DeleteObject(screenbitmap); memDC.DeleteDC(); return TRUE; } // 近似值,我们求中心点没必要无限逼近,差不多就行了 static bool IsApproximate(double value1, double value2) { return fabs(value1 - value1) <= 5; } /** * 求出这个线段上距离为指定长度的点 * * \param x1 第一个点 x 坐标 * \param y1 第一个点 y 坐标 * \param x1 第二个点 x 坐标 * \param y1 第二个点 y 坐标 * \param targetDistance 目标长度 */ static NBase::CPoint2D targetDistancePoint(const NBase::CPoint2D &point1, const NBase::CPoint2D &point2, double targetDistance) { double x1 = point1.x0; double y1 = point1.y0; double x2 = point2.x0; double y2 = point2.y0; double halfX = (x1 + x2) / 2; double halfY = (y1 + y2) / 2; double distance = point1.Distance(point2); if (distance < targetDistance) { return { -1, -1 }; } double middleDistance = distance / 2; if (IsApproximate(middleDistance, targetDistance)) { return { halfX, halfY }; } if (middleDistance > targetDistance) { return targetDistancePoint({ x1, y1 }, { halfX, halfY }, targetDistance); } else { return targetDistancePoint({ halfX, halfY }, { x2, y2 }, targetDistance - middleDistance); } } // 获取 Mesh static CMesh* GetMesh(CSigmaView* pView) { CXy* pXy = pView->m_pDoc->m_pXy; POSITION pt = pXy->FindFirstElement(DOUBLEFOX_MESH); if (pt == nullptr) { return nullptr; } COne* pOne = pXy->GetAt(pt); return (CMesh*)pOne->GetValue(); } /** * 计算线段的垂直相交线 * * \param point1 * \param point2 * \param crossPoint 交点,这个点必须在线段上 * \param horizontal_distance 垂直线段从交点向左/向右偏移的x轴距离 * * \return 返回垂直相交的线段 */ static std::pair PerpendicularLine( const NBase::CPoint2D& point1, const NBase::CPoint2D& point2, const NBase::CPoint2D& crossPoint, double horizontal_distance) { std::pair result; int distance = horizontal_distance; if (point1.x0 == point2.x0) // 如果线段是垂直的,那么只需要水平做一条线即可 { result.first.x0 = crossPoint.x0 - distance; result.first.y0 = crossPoint.y0; result.second.x0 = crossPoint.x0 + distance; result.second.y0 = crossPoint.y0; } else if (point1.y0 == point2.y0) // 如果线段是水平的,那么只需要垂直做一条线即可 { result.first.x0 = crossPoint.x0; result.first.y0 = crossPoint.y0 - distance; result.second.x0 = crossPoint.x0; result.second.y0 = crossPoint.y0 + distance; } else // 否则通过斜率来计算 { double slope = CalcSlope(point1.x0, point1.y0, point2.x0, point2.y0); double perpendicularSlope = -1 / slope; // 两条线垂直时,斜率的乘积为-1 result.first.x0 = crossPoint.x0 - distance; result.first.y0 = perpendicularSlope * (result.first.x0 - crossPoint.x0) + crossPoint.y0; // 计算垂直相交线的起点 result.second.x0 = crossPoint.x0 + distance; result.second.y0 = perpendicularSlope * (result.second.x0 - crossPoint.x0) + crossPoint.y0; // 计算垂直相交线的终点 } return result; } /** * 计算出折线的中间点以及中间点所在的线段 * * \param startPoint 出参,线段起始位置 * \param endPoint 出参,线段结束 位置 * \param middlPoint 出参,中间点 */ static void CurveMiddlePoint(CCurveEx* pCurve, NBase::CPoint2D *startPoint, NBase::CPoint2D *endPoint, NBase::CPoint2D *middlePoint) { double totalDistance = 0.0; std::vector distances; // 计算折线总长度和每一段的长度 for (int i = 0; i < pCurve->num - 1; i++) { NBase::CPoint2D point1{ pCurve->x[i], pCurve->y[i] }; NBase::CPoint2D point2{ pCurve->x[i + 1], pCurve->y[i + 1] }; double distance = point1.Distance(point2); totalDistance += distance; distances.push_back(distance); } // 计算出中间点的距离 double middleDistance = totalDistance / 2; // 中间那条线段前面所有线段的长度 double sum = 0.0; // 找出中间点所在的直线 size_t i = 0; for (i = 0; i < distances.size(); i++) { if (sum + distances[i] > middleDistance) { break; } sum += distances[i]; } double x1 = pCurve->x[i]; double y1 = pCurve->y[i]; double x2 = pCurve->x[i + 1]; double y2 = pCurve->y[i + 1]; *startPoint = NBase::CPoint2D{ x1, y1 }; *endPoint = NBase::CPoint2D{ x2, y2 }; // 计算出折线的中心点 *middlePoint = targetDistancePoint(*startPoint, *endPoint, middleDistance - sum); } // 曲线方向 enum class CurveOrientation { LowToHigh, // 从低到高 HightToLow, // 从高到低 }; /** * 判断点落在线的左侧、右侧、还是线段上,利用向量的叉积 * * \param line 线,方向从 pair 的 first 到 second * \param point 点 * \return >0 左侧,<0 右侧,=0 线段上 */ static int PointPositionOfLine(const std::pair &line, const NBase::CPoint2D &point) { double px = line.first.x0; double py = line.first.y0; double qx = line.second.x0; double qy = line.second.y0; double lx = point.x0; double ly = point.y0; double m = (qx - px) * (ly - py) - (qy - py) * (lx - px); return m; } /** * 计算断层的方向,0 表示 从低到高,1 表示从高到低 * * \param pView * \param pCurve * \param orientation 出参,断层方向 * * \return */ static int CalcCurveOrientation(CMesh *pMesh, CCurveEx *pCurve) { NBase::CPoint2D point1; NBase::CPoint2D point2; NBase::CPoint2D crossPoint; double dx = 0.0; double dy = 0.0; pMesh->GetDelt(dx, dy); // 这个距离使用两个空格宽度,由于网格大小是可以改变的,这里动态获取而不写死一个固定值,防止两个点落在同一网格内 double horizontal_distance = dx * 2; CurveMiddlePoint(pCurve, &point1, &point2, &crossPoint); // 计算出垂直相交线 std::pair perpendicularLine = PerpendicularLine(point1, point2, crossPoint, horizontal_distance); // 求出两边的 z 值 double z1 = pMesh->GetValue(perpendicularLine.first.x0, perpendicularLine.first.y0); double z2 = pMesh->GetValue(perpendicularLine.second.x0, perpendicularLine.second.y0); // 取最高的点 const NBase::CPoint2D *pPoint = &point1; if (z1 < z2) { pPoint = &point2; } // 通过叉乘判断最高点是在左侧还是右侧 // 让它们都落在一侧即可 return PointPositionOfLine(perpendicularLine, *pPoint) > 0 ? 1 : 0; } extern "C" __declspec(dllexport) int AdjustDirectionAutomatically(CSigmaView *pView, int orientation) { // 防止别人传递 0 1 以外的数据 orientation = (orientation == 0) ? 1 : 0; CSigmaDoc *pDoc = pView->m_pDoc; CXy* pXy = pDoc->m_pXy; CMesh* pMesh = GetMesh(pView); if (pMesh == nullptr) { return 0; } CString layerName = pXy->GetFaultLayer(); CLayer* pLayer = pXy->FindLayer(layerName); if (pLayer == nullptr) { return 0; } NBase::CPositionList needReversePositions; std::list needReverseCurves; NBase::CPositionList posList; int nCount = pXy->GetElement(pLayer, posList, DOUBLEFOX_CURVE); if (nCount == 0) { return 0; } CListForEach(pos, posList) { POSITION pt = posList.GetAt(pos); COne* pOne = pXy->GetAt(pt); CCurveEx *pCurve = (CCurveEx *)(pOne->value); if (IsPolygon(pCurve)) { continue; } if (CalcCurveOrientation(pMesh, pCurve) != orientation) { needReversePositions.AddTail(pt); needReverseCurves.push_back(pCurve); } } if (needReversePositions.GetCount() == 0) { return 0; } pDoc->SetActionItem(new CActionCurveReversalItem(pDoc, ID_OPERATION_CURVE_REVERSAL, needReversePositions)); pDoc->Modified(); for (CCurveEx* pCurve : needReverseCurves) { pCurve->Reversal(); } return needReversePositions.GetCount(); } static POSITION GetFirstLayerPosition(CXy* pXy, CString strLayer) { CLayerName layerName(strLayer); CLayerList* pClassList = pXy->GetClass(layerName.GetClassName()); if (pClassList == NULL) { return NULL; } strLayer = layerName.GetPathName(); strLayer.MakeLower(); POSITION pos = pClassList->GetHeadPosition(); while (pos) { CLayer *pLayer = pClassList->GetAt(pos); CString str = pLayer->GetName(); str.MakeLower(); if (str.Find(strLayer) == 0) //不能与当前要移动的类别相同,如果相同时,以下一个为止 break; pClassList->GetNext(pos); } return pos; } /** * 查找当前层同级别前面的图层, * * \param pXy * \param currLayer * \return 存在返回前面图层名称,失败返回空字符串 */ static CString GetPrevLayer(CXy* pXy, CString layer) { CLayerName layerName(layer); CString layerPath = layerName.GetFullPathName(); layerPath.MakeLower(); CLayerList *pClass = pXy->GetClass(layerName.GetClassName()); CString parentLayer = GetParentLayerPath(layerName.GetPathName()); bool hasFind = false; CListForEachReverse(pos, *pClass) { CLayer* pLayer = pClass->GetAt(pos); CString currLayerPath = CLayerName(pLayer->GetName()).GetFullPathName(); CString currParentLayerPath = GetParentLayerPath(currLayerPath); currLayerPath.MakeLower(); // 注意:尽量统一使用 FullPathName 来对比,因为它存在路径中带 Class 和 不带 Class 的情况 // 比如说:Layer:\aa 和 aa 其实是同一路径 if (currLayerPath.CompareNoCase(layerPath) == 0) // 找到图层 { hasFind = true; continue; } if (hasFind) { // 找到它前面第一个 parent 相同的元素 if (currParentLayerPath.CompareNoCase(currParentLayerPath) == 0) { return currLayerPath; } } } return ""; } /** * 获取移动后的名称 * * \param oldPath 移动前的路径 * \param parentPath 移动后的路径 * \return */ static CString GetMovedLayerPath(const CString& oldPath, const CString& parentPath) { CString fileName = PathFindFileName(oldPath); CString targetLayerName; targetLayerName.Format("%s\\%s", parentPath, fileName); return targetLayerName; } static CString GetParentPath(const CString& path) { int index = path.ReverseFind('\\'); if (index != -1) { return path.Left(index); } return ""; } /** * 拖拽图层 * \param pView * \param positioinLayer 移动到的位置所在的图层 * \param darggedLayer 被拖拽的图层 */ extern "C" __declspec(dllexport) void LayerDragged(CSigmaView * pView, wchar_t* targetLayer, wchar_t* draggedLayer, bool beChild) { CXy* pXy = pView->m_pDoc->m_pXy; CString strTargetLayer(targetLayer); CString strDraggedLayer(draggedLayer); if (strDraggedLayer == strTargetLayer) { return; } POSITION posInsert = GetFirstLayerPosition(pXy, strTargetLayer); int count = 0; CString targetParentLayer = GetParentLayerPath(strTargetLayer); CString draggedParentLayer = GetParentLayerPath(strDraggedLayer); CLayerLocation oldLocation; oldLocation.layer = strDraggedLayer; oldLocation.prevLayer = GetPrevLayer(pXy, oldLocation.layer); CLayerLocation newLocation; if (beChild) { count = pXy->MoveLayer(strDraggedLayer, strTargetLayer); if (count > 0) { newLocation.layer = GetMovedLayerPath(strDraggedLayer, strTargetLayer); newLocation.prevLayer = GetPrevLayer(pXy, newLocation.layer); } } else if (targetParentLayer == draggedParentLayer) // 同一父级类别下,移到到同级别,仅是上下顺序不同时 { count = pXy->MoveLayerInSameClassSeries(strDraggedLayer, TRUE, posInsert); if (count > 0) { newLocation.layer = strDraggedLayer; newLocation.prevLayer = GetPrevLayer(pXy, newLocation.layer); } } else { count = pXy->MoveLayer(strDraggedLayer, targetParentLayer, TRUE, posInsert); if (count > 0) { newLocation.layer = GetMovedLayerPath(strDraggedLayer, strTargetLayer); newLocation.prevLayer = GetPrevLayer(pXy, newLocation.layer); } } if (count > 0) { pView->m_pDoc->SetActionItem(new CActionLayerDragDropItem(pView->m_pDoc, oldLocation, newLocation)); } } /** * @brief 获取函数调用执行状态码 * * @param pView * @return int 执行状态码 */ extern "C" __declspec(dllexport) int GetStatusCode(CSigmaView * pView) { CItem* pItem = nullptr; if (pView) { pItem = pView->GetItem(); } if (pItem) { return pItem->GetStatusCode(); } return STATUS_CODE_FAILED; } /** * @brief 获取函数调用执行消息 * * @param pView * @return const char* 消息文本 */ extern "C" __declspec(dllexport) const char* GetStatusText(CSigmaView * pView) { CItem* pItem = nullptr; if (pView) { pItem = pView->GetItem(); } if (pItem) { return pItem->GetStatusText(); } return nullptr; } struct DeduplicateOption { std::string Type; // 要去重的图元 double MaxErorr = std::numeric_limits::epsilon(); // 最大精度; bool CompareLayer = false; // 只对相同图层内的图元进行去重 bool CompareElementName = false; // 对比图元名称 bool CompareEmbellishName = false; // 对比修饰符号名称 }; static std::optional LoadDeleteDupElementsOption(const std::string &xml) { DeduplicateOption option; TiXmlDocument xmlDoc; xmlDoc.Parse(xml.c_str()); TiXmlElement* root = xmlDoc.RootElement(); if (root == nullptr) { return std::nullopt; } TiXmlElement* typeElement = root->FirstChildElement("Type"); TiXmlElement* maxErrorElement = root->FirstChildElement("MaxError"); TiXmlElement* compareLayerElement = root->FirstChildElement("CompareLayer"); TiXmlElement* compareElementNameElement = root->FirstChildElement("CompareElementName"); if (typeElement == nullptr || maxErrorElement == nullptr || compareLayerElement == nullptr || compareElementNameElement == nullptr) { return std::nullopt; } std::vector types{ "Point", "Curve", "PointAndCurve" }; if (!Contains(types, std::string(typeElement->GetText()))) { return std::nullopt; } option.Type = typeElement->GetText(); try { option.MaxErorr = std::stod(maxErrorElement->GetText()); } catch (...) { return std::nullopt; } const char* compareLayer = compareLayerElement->GetText(); option.CompareLayer = (std::string_view(compareLayer) == "true"); const char* compareElementName = compareElementNameElement->GetText(); option.CompareElementName = (std::string_view(compareElementName) == "true"); return option; } static bool IsPoint(COne* pOne) { switch (pOne->GetType()) { case DOUBLEFOX_XYZ: case DOUBLEFOX_POINT: case DOUBLEFOX_CROSSPOINT: case DOUBLEFOX_TWOPOINT: return true; } return false; } static bool IsCurve(COne* pOne) { return pOne->GetType() == DOUBLEFOX_CURVE; } /** * 图元判重类,目前仅支持点和线 */ class DupComparer { public: DupComparer(const DeduplicateOption& option) : m_option(option) { } bool Compare(const COne* pLeft, const COne* pRight) const { COne* left = const_cast(pLeft); COne* right = const_cast(pRight); // 如果用户传入相同对象,我们这里返回 false,我们不希望用户传入相同对象 if (left == right) { return false; } // 如果两个元素类型不相同,显然不做除重 if (left->GetType() != right->GetType()) { return false; } // 如果不是我们关心的类型,直接略过 if (!MatchOptionType(left)) { return false; } // 用户决定是否只对同一图层进行去重 if (m_option.CompareLayer && (left->GetLayer()->GetPathName() != right->GetLayer()->GetPathName())) { return false; } /* if (m_option.CompareEmbellishName) { CHowToViewPoint* leftHowToViewPoint = left->GetHowToViewPoint(); CHowToViewPoint* rightHowToViewPoint = right->GetHowToViewPoint(); if (!IsDupHowToViewPoint(leftHowToViewPoint, rightHowToViewPoint)) { return false; } CHowToViewCurve* leftHowToViewCurve = left->GetHowToViewCurve(); CHowToViewCurve* rightHowToViewCurve = right->GetHowToViewCurve(); if (!IsDupHowToViewCurve(leftHowToViewCurve, rightHowToViewCurve)) { return false; } } */ if (m_option.CompareElementName && (left->GetName() != right->GetName())) { return false; } int leftType = left->GetType(); if (IsPoint(left)) { CPointNameEx* leftPoint = (CPointNameEx*)(left->GetValue()); CPointNameEx* rightPoint = (CPointNameEx*)(right->GetValue()); return IsDupPoint(leftPoint, rightPoint); } else if (IsCurve(left)) { CCurveEx* leftCurve = (CCurveEx*)(left->GetValue()); CCurveEx* rightCurve = (CCurveEx*)(right->GetValue()); return IsDupCurve(leftCurve, rightCurve); } return false; } bool MatchOptionType(COne* left) const { if (m_option.Type == "Point") { return IsPoint(left); } else if (m_option.Type == "Curve") { return IsCurve(left); } else if (m_option.Type == "PointAndCurve") { return IsPoint(left) || IsCurve(left); } return false; } private: bool IsDupPoint(CPointNameEx* left, CPointNameEx* right) const { DoubleComparator comparator(m_option.MaxErorr); return comparator.IsEqual(left->x0, right->x0) && comparator.IsEqual(left->y0, right->y0) && comparator.IsEqual(left->z0, right->z0); } bool IsDupCurve(CCurveEx* left, CCurveEx* right) const { DoubleComparator comparator(m_option.MaxErorr); if (left->num != right->num) { return false; } for (int i = 0; i < left->num; i++) { if (!comparator.IsEqual(left->x[i], right->x[i])) { return false; } if (!comparator.IsEqual(left->y[i], right->y[i])) { return false; } if (!comparator.IsEqual(left->z[i], right->z[i])) { return false; } } return true; } bool IsDupHowToViewPoint(CHowToViewPoint *left, CHowToViewPoint *right) const { if (left == nullptr && right == nullptr) { return true; } if (left == nullptr && right != nullptr) { return false; } if (left != nullptr && right == nullptr) { return false; } return left->GetName() == right->GetName(); } template bool IsSame(CCurveView* left, CCurveView* right) const { T* leftView = dynamic_cast(left); T* rightView = dynamic_cast(right); if (leftView != nullptr && rightView != nullptr) { return leftView->MarkName == rightView->MarkName; } return false; } /// /// 比较内容而非指针本身 /// /// array /// view /// true/false bool ContainsSame(CArray& array, CCurveView* view) const { for (int i = 0; i < array.GetSize(); i++) { CCurveView* curr = array.GetAt(i); if (typeid(*curr) != typeid(*view)) { continue; } // CCurveLocate 和 CCurveLoateEx 先不处理,它们没有 MarkName, // 其它的都是下面的类或子类,已经处理完毕 if (IsSame(curr, view) || IsSame(curr, view) || IsSame(curr, view) || IsSame(curr, view)) { return true; } } return false; } bool IsSubSet(CArray &subSet, CArray &set) const { for (int i = 0; i < subSet.GetSize(); i++) { if (!ContainsSame(set, subSet.GetAt(i))) { return false; } } return true; } bool IsDupHowToViewCurve(CHowToViewCurve *left, CHowToViewCurve *right) const { CArray* leftArray = left->GetValueArray(); CArray* rightArray = right->GetValueArray(); if (left == nullptr || right == nullptr) { return left == right; } return (leftArray->GetSize() == rightArray->GetSize()) && IsSubSet(*leftArray, *rightArray); } DeduplicateOption m_option; }; static bool ExistDuplicateElement(std::vector& vec, COne* pOne, const DupComparer &comparer) { return AnyOf(vec, [pOne, &comparer](COne* pCurr) { return comparer.Compare(pCurr, pOne); }); } /** * 删除重复图元 * \param pXy 图件 * \param filters 删除条件 * 类型:要对哪些类型的图元去重 * 最大误差: 在误差范围内才认为是重复图元 * 同一图层: 是否只对同一图层图元进行去重 * 修饰:修饰也相同才判定为重复图元 * 比较图元名称:是否要名称相同才认为是重复图元 */ extern "C" __declspec(dllexport) void XyDeleteDupElements(CSigmaView *pView, const wchar_t *option) { assert(pView != nullptr); CXy* pXy = pView->m_pDoc->m_pXy; std::string xml = WStringToString(option); std::optional dedupOption = LoadDeleteDupElementsOption(xml); if (!dedupOption) { // 如果格式不正确,使用默认值 dedupOption = DeduplicateOption(); } std::vector vec; NBase::CPositionList delList; DupComparer comparer(dedupOption.value()); CPtrList* pValueList = pXy->GetValueList(); for (POSITION pos = pValueList->GetHeadPosition(); pos != nullptr; pValueList->GetNext(pos)) { COne* pOne = (COne *)pValueList->GetAt(pos); if (ExistDuplicateElement(vec, pOne, comparer)) { delList.AddTail(pos); } else { vec.push_back(pOne); } } if (delList.GetSize() > 0) { pView->m_pDoc->SetActionItem(new CActionDeleteItem(pView->m_pDoc, IDS_STRING_ACTION_DELETE, delList)); } } extern "C" __declspec(dllexport) void SetVtkDataNodeChecked(CSigmaView *pView, void* nodeData, bool checked) { KevVtkDataNode *pData = (KevVtkDataNode *)nodeData; pData->m_checked = checked; } extern "C" __declspec(dllexport) void SetVtkDataNodeHide(CSigmaView *pView, void* nodeData, bool isHide) { KevVtkDataNode *pData = (KevVtkDataNode *)nodeData; pData->m_hide = isHide; } extern "C" __declspec(dllexport) void AddVtkDataNodeChild(CSigmaView *pView, void* pParent, void* pChild) { KevVtkDataNode *pp = (KevVtkDataNode *)pParent; KevVtkDataNode *pc = (KevVtkDataNode *)pChild; pp->m_childList.push_back(pc); } void GetClosedDefaultList(void* pData, std::list &curveList) { if (pData == nullptr) return; KevVtkDataNode* pKevVtkData = (KevVtkDataNode*)pData; std::list::iterator itCurve; for (itCurve = (pKevVtkData->m_closedFaultCCurveList).begin(); itCurve != (pKevVtkData->m_closedFaultCCurveList).end(); ++itCurve) { curveList.push_back(*itCurve); } //获取子节点闭合曲线 std::list::iterator itData; for (itData = (pKevVtkData->m_childList).begin(); itData != (pKevVtkData->m_childList).end(); ++itData) { GetClosedDefaultList(*itData, curveList); } } void GetWellPointList(void* pData, std::list &wellPointList) { if (pData == nullptr) return; KevVtkDataNode* pKevVtkData = (KevVtkDataNode*)pData; std::list::iterator itCurve; for (itCurve = (pKevVtkData->m_pointList).begin(); itCurve != (pKevVtkData->m_pointList).end(); ++itCurve) { wellPointList.push_back(*itCurve); } //获取子节点闭合曲线 std::list::iterator itData; for (itData = (pKevVtkData->m_childList).begin(); itData != (pKevVtkData->m_childList).end(); ++itData) { GetWellPointList(*itData, wellPointList); } } void GetCloseBoundaryList(void* pData, std::list &curveList) { if (pData == nullptr) return; KevVtkDataNode* pKevVtkData = (KevVtkDataNode*)pData; std::list::iterator itCurve; for (itCurve = (pKevVtkData->m_closedBoundaryList).begin(); itCurve != (pKevVtkData->m_closedBoundaryList).end(); ++itCurve) { curveList.push_back(*itCurve); } //获取子节点闭合曲线 std::list::iterator itData; for (itData = (pKevVtkData->m_childList).begin(); itData != (pKevVtkData->m_childList).end(); ++itData) { GetCloseBoundaryList(*itData, curveList); } } extern "C" __declspec(dllexport) void ProcessMeshBoundary(CSigmaView *pView, void* pRootDataNode, void* pMainMesh) { KevVtkDataNode *pData = (KevVtkDataNode *)pRootDataNode; KevVtkMeshData *pMeshData = (KevVtkMeshData *)pMainMesh; //恢复原始数据 std::list boundaryList; GetCloseBoundaryList(pRootDataNode, boundaryList); CCurveEx* pCurve = nullptr; if (!boundaryList.empty()) { pCurve = (CCurveEx *)(boundaryList.front()); } int row = pMeshData->numX;//每行的点数,X轴上点的数量 int col = pMeshData->numY;//每列的点的数量,Y轴上点的数量 if (boundaryList.size() < 1) { return; } //#pragma omp parallel for for (long j = 0; j < col; j++) { for (long i = 0; i < row; i++) { long k = 0;//传入的网格数据索引 long pi = 0; double x = 0, y = 0, z = 0; pi = j * row + i;//点集索引 x = pMeshData->P0[0] + pMeshData->delt[0] * (i); y = pMeshData->P0[1] + pMeshData->delt[1] * (j); z = pMeshData->shadow_u[pi]; std::list::iterator itCurve; bool isInside = false; if (pCurve) { if (pCurve->IsInside(x, y)) { isInside = true; } } if (!isInside) { pMeshData->shadow_u[pi] = -1e100; } } } ////处理井点包含 //std::list tempList; //GetWellPointList(pData, tempList); //for (KevVtkPointData* point : tempList) { // if (point != nullptr) { // //只取第一条边界线 // if (pCurve) // { // if (pCurve->IsInside(point->m_x, point->m_y)) // { // pData->m_pointList.push_back(point); // } // } // } //} } extern "C" __declspec(dllexport) void ProcessMeshFaultArea(CSigmaView *pView, void* pRootDataNode, void* pMainMesh) { KevVtkDataNode *pData = (KevVtkDataNode *)pRootDataNode; KevVtkMeshData *pMeshData = (KevVtkMeshData *)pMainMesh; std::list faultList; GetClosedDefaultList(pRootDataNode, faultList); int row = pMeshData->numX;//每行的点数,X轴上点的数量 int col = pMeshData->numY;//每列的点的数量,Y轴上点的数量 if (faultList.size() < 1) { return; } //#pragma omp parallel for for (long j = 0; j < col; j++) { for (long i = 0; i < row; i++) { long k = 0;//传入的网格数据索引 long pi = 0; double x = 0, y = 0, z = 0; pi = j * row + i;//点集索引 x = pMeshData->P0[0] + pMeshData->delt[0] * (i); y = pMeshData->P0[1] + pMeshData->delt[1] * (j); z = pMeshData->shadow_u[pi]; //边界外的点不处理 if (std::fabs(z - (-1e100)) < 1e-6) { continue; } std::list::iterator itCurve; for (itCurve = (faultList).begin(); itCurve != (faultList).end(); ++itCurve) { CCurveEx* pCurve = (CCurveEx *)(*itCurve); if (pCurve->IsInside(x, y)) { pMeshData->shadow_u[pi] = -1e99; break; } } } } } extern "C" __declspec(dllexport) bool SaveMergeMesh(CSigmaView* pView, void* pMesh, const char* filename) { CXy* pXy = pView->m_pDoc->m_pXy; KepVtkMeshData* pKepVtkMesh = (KepVtkMeshData*)pMesh; if (pKepVtkMesh) { CMesh* mesh = new CMesh; CDimension3D* pdfg = new CDimension3D; pdfg->CDimension2D::Create(pKepVtkMesh->numX, pKepVtkMesh->numY, pKepVtkMesh->x0, pKepVtkMesh->y0, pKepVtkMesh->dx, pKepVtkMesh->dy); pdfg->range[0] = pKepVtkMesh->range[0]; pdfg->range[1] = pKepVtkMesh->range[1]; pdfg->total = pKepVtkMesh->numX * pKepVtkMesh->numY; std::memcpy(pdfg->u, pKepVtkMesh->u, pdfg->total * sizeof(double)); /*for (int j = 0; j < pKepVtkMesh->numY; j++) { for (int i = 0; i < pKepVtkMesh->numX; i++) { m_pDfg->SetValue(i, j, pSurface->m_pData[j * pSurface->numx + i]); } }*/ mesh->m_nTimes = 1; mesh->SetMesh(pdfg, MESH_DFG, false, -DBL_MAX); /*mesh->SetMeshType(MESH_DFG); mesh->Attach(pdfg, CMesh::typeDFG);*/ COne *pOne = new COne; pOne->SetValue(mesh, DOUBLEFOX_MESH); pXy->AddTailOne(pOne); //mesh->SetM(pKepVtkMesh->m_zMin, pKepVtkMesh->m_zMax); //mesh->GetMesh()->P0[0] = pKepVtkMesh->x0; //mesh->GetMesh()->P0[1] = pKepVtkMesh->y0; //mesh->GetMesh()->n = 2; //mesh->GetMesh()->delt[0] = pKepVtkMesh->dx; //mesh->GetMesh()->delt[1] = pKepVtkMesh->dy; //mesh->GetMesh()->num[0] = pKepVtkMesh->numX; //mesh->GetMesh()->num[1] = pKepVtkMesh->numY; //mesh->GetMesh()->range[0] = pKepVtkMesh->range[0]; //mesh->GetMesh()->range[1] = pKepVtkMesh->range[1]; //if (pdfg == NULL) // return false; //pdfg->n = 2; //pdfg->num[0] = pKepVtkMesh->num[0]; //pdfg->num[1] = pKepVtkMesh->num[1]; //pdfg->P0[0] = pKepVtkMesh->P0[0]; //pdfg->P0[1] = pKepVtkMesh->P0[1]; //pdfg->delt[0] = pKepVtkMesh->delt[0]; //pdfg->delt[1] = pKepVtkMesh->delt[1]; //pdfg->range[0] = pKepVtkMesh->range[0]; //pdfg->range[1] = pKepVtkMesh->range[1]; //pdfg->u = new double[pKepVtkMesh->numX * pKepVtkMesh->numY]; //std::memcpy(pdfg->u, pKepVtkMesh->u, pdfg->total * sizeof(double)); } pView->m_pDoc->SaveFile(filename); return true; } extern "C" __declspec(dllexport) void* GetKevFirstMesh(CSigmaView *pView) { CXy* pXy = pView->m_pDoc->m_pXy; NBase::CPositionList positionList; // 获取所有网格对象,包括不可编辑的元素 pXy->GetElement(DOUBLEFOX_MESH, positionList, true); POSITION posCurrent = positionList.GetHeadPosition(); POSITION posFirstFind = nullptr; while (posCurrent != NULL) { // 步骤 3: 使用 GetNext 获取当前迭代器位置的元素,并让迭代器步进到下一个位置 // 注意:这里 GetNext 返回的是链表存储的 POSITION 元素,其参数 posCurrent 会被自动更新 POSITION posElement = positionList.GetNext(posCurrent); COne* tempOne = pXy->GetAt(posElement); CLayer* layer = tempOne->GetLayer(); BYTE state = layer->GetState(); if (state != 12) { posFirstFind = posElement; break; } } //直接找第一个元素,可能找到的是非编辑不可见元素 //POSITION posFirstFind = pXy->FindFirstElement(DOUBLEFOX_MESH); if (posFirstFind == nullptr) { return nullptr; } COne* pOne = pXy->GetAt(posFirstFind); CString layerStr = pOne->GetLayerName(); CMesh* pMesh = (CMesh*)pOne->GetValue(); KevVtkMeshData* pKevVtkMesh = nullptr; if (pMesh != nullptr) { pKevVtkMesh = new KevVtkMeshData; pKevVtkMesh->m_layerName = layerStr; double zmin, zmax; pMesh->GetM(zmin, zmax); pKevVtkMesh->m_zMin = zmin; pKevVtkMesh->m_zMax = zmax; double x0, y0; pMesh->GetOrg(x0, y0); pKevVtkMesh->x0 = x0; pKevVtkMesh->y0 = y0; double dx, dy; pMesh->GetDelt(dx, dy); pKevVtkMesh->dx = dx; pKevVtkMesh->dy = dy; CGrid* pGrid = pMesh->GetMesh(); long numX = pGrid->xnum(); long numY = pGrid->ynum(); pKevVtkMesh->numX = numX; pKevVtkMesh->numY = numY; CDimension3D* pdfg = pMesh->GetDfg(); if (pdfg == NULL) return nullptr; pKevVtkMesh->n = pdfg->n; pKevVtkMesh->num = pdfg->num; pKevVtkMesh->P0 = pdfg->P0; pKevVtkMesh->delt = pdfg->delt; pKevVtkMesh->range = pdfg->range; pKevVtkMesh->origin_u = pdfg->u; pKevVtkMesh->shadow_u = new double[pdfg->total]; std::memcpy(pKevVtkMesh->shadow_u, pdfg->u, pdfg->total * sizeof(double)); for (int i = 0; i < pMesh->color.sizeColor(); i++) { CColorItem& item = pMesh->color.GetColorItem(i); KevVtkColorItem* pColorItem = new KevVtkColorItem(); pColorItem->z = item.z; pColorItem->color[0] = item.color.rgbRed; pColorItem->color[1] = item.color.rgbGreen; pColorItem->color[2] = item.color.rgbBlue; pColorItem->color[3] = item.color.rgbReserved; pColorItem->gradient = item.m_bContinue; pKevVtkMesh->m_colorList.push_back(pColorItem); } } return pKevVtkMesh; } extern "C" __declspec(dllexport) void* GetFirstMesh(CSigmaView *pView) { CXy* pXy = pView->m_pDoc->m_pXy; POSITION pt = pXy->FindFirstElement(DOUBLEFOX_MESH); if (pt == nullptr) { return nullptr; } COne* pOne = pXy->GetAt(pt); CString layerStr = pOne->GetLayerName(); CMesh* pMesh = (CMesh*)pOne->GetValue(); KepVtkMeshData* pKepVtkMesh = nullptr; if (pMesh != nullptr) { pKepVtkMesh = new KepVtkMeshData; pKepVtkMesh->m_layerName = layerStr; double zmin, zmax; pMesh->GetM(zmin, zmax); pKepVtkMesh->m_zMin = zmin; pKepVtkMesh->m_zMax = zmax; double x0, y0; pMesh->GetOrg(x0, y0); pKepVtkMesh->x0 = x0; pKepVtkMesh->y0 = y0; double dx, dy; pMesh->GetDelt(dx, dy); pKepVtkMesh->dx = dx; pKepVtkMesh->dy = dy; CGrid* pGrid = pMesh->GetMesh(); long numX = pGrid->xnum(); long numY = pGrid->ynum(); pKepVtkMesh->numX = numX; pKepVtkMesh->numY = numY; CDimension3D* pdfg = pMesh->GetDfg(); if (pdfg == NULL) return nullptr; pKepVtkMesh->n = pdfg->n; pKepVtkMesh->num[0] = pdfg->num[0]; pKepVtkMesh->num[1] = pdfg->num[1]; pKepVtkMesh->P0[0] = pdfg->P0[0]; pKepVtkMesh->P0[1] = pdfg->P0[1]; pKepVtkMesh->delt[0] = pdfg->delt[0]; pKepVtkMesh->delt[1] = pdfg->delt[1]; pKepVtkMesh->range[0] = pdfg->range[0]; pKepVtkMesh->range[1] = pdfg->range[1]; pKepVtkMesh->u = new double[pdfg->total]; std::memcpy(pKepVtkMesh->u, pdfg->u, pdfg->total * sizeof(double)); for (int i = 0; i < pMesh->color.sizeColor(); i++) { CColorItem& item = pMesh->color.GetColorItem(i); KevVtkColorItem* pColorItem = new KevVtkColorItem(); pColorItem->z = item.z; pColorItem->color[0] = item.color.rgbRed; pColorItem->color[1] = item.color.rgbGreen; pColorItem->color[2] = item.color.rgbBlue; pColorItem->color[3] = item.color.rgbReserved; pColorItem->gradient = item.m_bContinue; pKepVtkMesh->m_colorList.push_back(pColorItem); } } return pKepVtkMesh; } std::vector split(const std::string& s, char delimiter) { std::vector tokens; std::stringstream ss(s); std::string token; while (std::getline(ss, token, delimiter)) { tokens.push_back(token); } return tokens; } void GetLayerClosedCurveList(CSigmaView *pView, LPCTSTR layerName, std::list &closedCurveList) { CXy *pXy = pView->m_pDoc->GetDraw(); if (pXy == nullptr) return; NBase::CPositionList elements; //获取图层中的所有元素,不包含子图层, 包括不可编辑 pXy->GetElement(layerName, elements, false, TRUE); POSITION p = nullptr; COne *pOne = nullptr; POSITION pos; pos = elements.GetHeadPosition(); while (pos) { p = elements.GetNext(pos); pOne = (COne *)pXy->GetValueList()->GetAt(p); int type = pOne->GetType(); switch (type) { case DOUBLEFOX_CURVE: { CCurveEx *pCurve = (CCurveEx *)pOne->GetValue(); if (pCurve->IsClosed()) { closedCurveList.push_back(pCurve); } } break; default: break; } } } extern "C" __declspec(dllexport) void PreProcessMeshData(CSigmaView *pView, void *pKevMeshData, const char *faultLayers, const char *boundaryLayer) { if (pKevMeshData == nullptr) { return; } // 获取图件对象 CXy* pXy = pView->m_pDoc->m_pXy; // 解析断层图层字符串,以‘;’分割 std::string faultStr = std::string(faultLayers); std::vector faultVec = split(faultStr, ';'); std::list faultClosedCurveList; //获取断层图层的所有闭合曲线 for (int i = 0; i < faultVec.size(); i++) { GetLayerClosedCurveList(pView, faultVec[i].c_str(), faultClosedCurveList); } //获取边界图层的所有闭合曲线 std::list boundaryClosedCurveList; GetLayerClosedCurveList(pView, boundaryLayer, boundaryClosedCurveList); KepVtkMeshData *pMeshData = (KepVtkMeshData*)(pKevMeshData); int numx = pMeshData->numX;//每行的点数,X轴上点的数量 int numy = pMeshData->numY;//每列的点的数量,Y轴上点的数量 // 网格数据是逐行在z值中存放的 //优先处理边界限定 if (boundaryClosedCurveList.size() > 0) { CCurveEx* pCurve = boundaryClosedCurveList.front(); //#pragma omp parallel for for (long j = 0; j < numy; j++) { for (long i = 0; i < numx; i++) { long k = 0;//传入的网格数据索引 long pi = 0; double x = 0, y = 0, z = 0; pi = j * numx + i;//点集索引 x = pMeshData->P0[0] + pMeshData->delt[0] * (i); y = pMeshData->P0[1] + pMeshData->delt[1] * (j); z = pMeshData->u[pi]; std::list::iterator itCurve; bool isInside = false; if (pCurve->IsInside(x, y)) { ; } else { // 边界外的点,z值给一个最小的负数 pMeshData->u[pi] = -DBL_MAX;// 原始数据被预处理,使用影子数组 } } } } //TOD0:两个#pragma omp parallel for放在一起无法同步 //处理断层限定 //#pragma omp parallel for for (long j = 0; j < numy; j++) { for (long i = 0; i < numx; i++) { long k = 0;//传入的网格数据索引 long pi = 0; double x = 0, y = 0, z = 0; pi = j * numx + i;//点集索引 x = pMeshData->P0[0] + pMeshData->delt[0] * (i); y = pMeshData->P0[1] + pMeshData->delt[1] * (j); z = pMeshData->u[pi]; if (abs(z - (-1e8)) < 1e-3) { continue; } std::list::iterator itCurve; // x,y 在任何一条断层范围内,该点Z值设为最小负数 for (itCurve = (faultClosedCurveList).begin(); itCurve != (faultClosedCurveList).end(); ++itCurve) { CCurveEx* pCurve = (CCurveEx *)(*itCurve); if (pCurve->IsInside(x, y)) { pMeshData->u[pi] = -DBL_MAX; break; } } } } } extern "C" __declspec(dllexport) void* GetLayerData(CSigmaView *pView, LPCTSTR layerName, bool bBoundaryLayer, bool bFaultLayer, bool bWellLayer) { KevVtkDataNode *pData = new KevVtkDataNode(); pData->m_layerName = layerName; pData->m_bBorderLayer = bBoundaryLayer; pData->m_bFaultLayer = bFaultLayer; pData->m_bWellLayer = bWellLayer; CXy *pXy = pView->m_pDoc->GetDraw(); if (pXy == nullptr) return pData; NBase::CPositionList elements; //获取图层元素,不包含子图层 pXy->GetElement(layerName, elements, false); POSITION p = nullptr; COne *pOne = nullptr; POSITION pos; pos = elements.GetHeadPosition(); while (pos) { p = elements.GetNext(pos); pOne = (COne *)pXy->GetValueList()->GetAt(p); int type = pOne->GetType(); switch (type) { case DOUBLEFOX_POINT: { KevVtkPointData *pKevVtkPoint = new KevVtkPointData; CPointNameEx *pPoint = (CPointNameEx *)pOne->GetValue(); pKevVtkPoint->m_name = pPoint->GetName().GetString(); pKevVtkPoint->m_x = pPoint->x0; pKevVtkPoint->m_y = pPoint->y0; pKevVtkPoint->m_z = pPoint->z0; pKevVtkPoint->m_layerName = layerName; pData->m_pointList.push_back(pKevVtkPoint); } break; case DOUBLEFOX_CURVE: { KevVtkCurveData *pKevVtkCurve = new KevVtkCurveData; CCurveEx *pCurve = (CCurveEx *)pOne->GetValue(); pKevVtkCurve->m_layerName = layerName; pKevVtkCurve->m_name = pCurve->GetName().GetString(); pKevVtkCurve->x = pCurve->x; pKevVtkCurve->y = pCurve->y; pKevVtkCurve->z = pCurve->z; pKevVtkCurve->l = pCurve->l; pKevVtkCurve->m_num = pCurve->num; pKevVtkCurve->m_nPoint = pCurve->nPoint; pKevVtkCurve->isClosed = pCurve->IsClosed(); pData->m_curveList.push_back(pKevVtkCurve); if (bFaultLayer) { if (pCurve->IsClosed()) { pData->m_closedFaultCCurveList.push_back(pCurve); pData->m_closedFaultVtkCurveList.push_back(pKevVtkCurve); } else { pData->m_singleFaultVtkCurveList.push_back(pKevVtkCurve); } } if (bBoundaryLayer) { if (pCurve->IsClosed()) { pData->m_closedBoundaryVtkCurveList.push_back(pKevVtkCurve); pData->m_closedBoundaryList.push_back(pCurve); } } } break; case DOUBLEFOX_MESH: { KevVtkMeshData *pKevVtkMesh = new KevVtkMeshData; CMesh *pMesh = (CMesh *)pOne->GetValue(); double zmin, zmax; pMesh->GetM(zmin, zmax); pKevVtkMesh->m_zMin = zmin; pKevVtkMesh->m_zMax = zmax; double x0, y0; pMesh->GetOrg(x0, y0); pKevVtkMesh->x0 = x0; pKevVtkMesh->y0 = y0; double dx, dy; pMesh->GetDelt(dx, dy); pKevVtkMesh->dx = dx; pKevVtkMesh->dy = dy; CGrid* pGrid = pMesh->GetMesh(); long numX = pGrid->xnum(); long numY = pGrid->ynum(); pKevVtkMesh->numX = numX; pKevVtkMesh->numY = numY; CDimension3D* pdfg = pMesh->GetDfg(); if (pdfg == NULL) return nullptr; pKevVtkMesh->num = pdfg->num; pKevVtkMesh->P0 = pdfg->P0; pKevVtkMesh->delt = pdfg->delt; double* pShadow = new double[pdfg->total]; std::memcpy(pShadow, pdfg->u, pdfg->total * sizeof(double)); pKevVtkMesh->shadow_u = pShadow; pKevVtkMesh->origin_u = pdfg->u; pKevVtkMesh->range = pdfg->range; pKevVtkMesh->n = pdfg->n; pKevVtkMesh->m_layerName = layerName; pKevVtkMesh->id = pMesh->GetId(); pData->m_meshList.push_back(pKevVtkMesh); CColorBase& color = pMesh->color; for (int i = 0; i < color.sizeColor(); i++) { CColorItem& item = color.GetColorItem(i); KevVtkColorItem *pColorItem = new KevVtkColorItem(); pColorItem->z = item.z; pColorItem->color[0] = item.color.rgbRed; pColorItem->color[1] = item.color.rgbGreen; pColorItem->color[2] = item.color.rgbBlue; pColorItem->color[3] = item.color.rgbReserved; pColorItem->gradient = item.m_bContinue; pKevVtkMesh->m_colorList.push_back(pColorItem); } } break; case DOUBLEFOX_IMAGE: { KevVtkImageData *pKevVtkImage = new KevVtkImageData; CImageInsert *pImage = (CImageInsert *)pOne->GetValue(); pKevVtkImage->m_x = pImage->x0; pKevVtkImage->m_y = pImage->y0; pKevVtkImage->m_width = pImage->m_size.cx; pKevVtkImage->m_height = pImage->m_size.cy; auto now = std::chrono::high_resolution_clock::now(); auto tick = std::chrono::duration_cast(now.time_since_epoch()).count(); std::string fileName = std::to_string(tick) + ".png"; pData->m_imageList.push_back(pKevVtkImage); //pImage->SaveAs(fileName.c_str()); pKevVtkImage->m_fileName = fileName; pKevVtkImage->m_layerName = layerName; } break; default: break; } } return pData; } extern "C" __declspec(dllexport) void DestroyAndInsertElement(CSigmaView* pView, int64_t* destroyArray, int32_t destroyLength, int64_t* insertArray, int32_t insertLength) { if (pView == nullptr) { TRACE("pView 不能为 nullptr\n"); return; } if (destroyArray == nullptr) { TRACE("destroyArray 不能为 nullptr\n"); return; } if (insertArray == nullptr) { TRACE("addArray 不能为 nullptr\n"); return; } auto pComboAction = std::make_unique(pView->m_pDoc, 0); CPositionList insertPositions; for (int32_t i = 0; i < insertLength; i++) { POSITION pos = reinterpret_cast(insertArray[i]); insertPositions.AddTail(pos); } auto pAddAction = std::make_unique(pView->m_pDoc, IDS_STRING_ACTION_ADD, insertPositions); pAddAction->Do(); pComboAction->AddAction(pAddAction.release()); CPositionList destroyPositions; for (int32_t i = 0; i < destroyLength; i++) { POSITION pos = reinterpret_cast(destroyArray[i]); destroyPositions.AddTail(pos); } CXy* pXy = pView->m_pDoc->m_pXy; auto pDeleteAction = std::make_unique(pView->m_pDoc, IDS_STRING_ACTION_DELETE, destroyPositions); pDeleteAction->Do(); pComboAction->AddAction(pDeleteAction.release()); pView->m_pDoc->SetActionItem(pComboAction.release()); } extern "C" __declspec(dllexport) void ReverseCurveAndMeshZValue(CSigmaView* pView) { ASSERT(pView != nullptr); CXyElementFilter filter; filter.addType(DOUBLEFOX_CURVE); filter.addType(DOUBLEFOX_MESH); NBase::CPositionList reversedList; pView->m_pDoc->m_pXy->GetElement(filter, reversedList); auto* pActionItem = new CActionReverseZItem(pView->m_pDoc, 0, reversedList); pView->m_pDoc->SetActionItem(pActionItem); } /** * 设置预处理文件启动目录 * * \param dirPath */ extern "C" __declspec(dllexport) void FileUtility_SetStartupDirectory(const wchar_t* dirPath) { SetApplicationStartupDirectory(CString(dirPath)); } extern "C" __declspec(dllexport) void EnableSnap(CSigmaView* pView, bool enable) { if (pView == nullptr || pView->m_pDoc == nullptr) { TRACE("pView 和 pView->m_pDoc 都不能为 nullptr\n"); return; } pView->m_pDoc->EnableSnap(enable); } /** * 删除橡皮擦参数 * * \param settings 参数,暂时先用一个简单字符串,后续如果有更多参数,再考虑使用 json 之类 */ extern "C" __declspec(dllexport) void SetEraserSettings(CSigmaView* pView, const LPCTSTR settings) { if (pView == nullptr) { return; } NItem::CItem * pItem = pView->m_pDoc->GetItem(); if (pItem == nullptr) { return; } CItemEraser* pItemEraser = dynamic_cast(pItem); if (pItemEraser == nullptr) { return; } CString normal = _T("Normal"); CString segments = _T("Segments"); CString nodes = _T("Nodes"); if (normal.CompareNoCase(settings) == 0) { pItemEraser->SetEraserMode(EraserMode::Normal); } else if (segments.CompareNoCase(settings) == 0) { pItemEraser->SetEraserMode(EraserMode::Segments); } else if (nodes.CompareNoCase(settings) == 0) { pItemEraser->SetEraserMode(EraserMode::Nodes); } } extern "C" __declspec(dllexport) void RegisterListener(CSigmaView* pView, Listener listener) { if (pView != nullptr) { pView->RegisterListener(listener); } } template static std::unique_ptr GetObjectProxy(CSigmaView* pView) { auto expected = TryGetItemCast(pView); if (expected.has_value()) { return GetInstace().Create(typeid(T).name(), expected.value()); } else { TRACE("%s\n", expected.error()); return nullptr; } } /** * 获取代理对象,这里先写一点,后续再完善 * * \param pView * \param itemName * \return */ static std::unique_ptr GetObjectProxy(CSigmaView* pView, const CString& itemName) { if (itemName == "ItemEraser") { CItem* pItem = pView->m_pDoc->GetItem(); CItemEraser* pItemEraser = dynamic_cast(pItem); if (pItemEraser != nullptr) { return std::make_unique(pItemEraser); } } return nullptr; } /** * 获取 Item 属性 * * \param itemName item 名称,用于描述要操作的对象 * \param property 属性名称 * \return 属性值,全部使用字符串,通用,如果当前 item 对应不上,将返回空字符串 */ extern "C" __declspec(dllexport) BSTR GetSigmaViewItemProperty(CSigmaView* pView, const LPCTSTR itemName, const LPCTSTR property) { if (pView == nullptr || pView->m_pDoc == nullptr) { TRACE("pView 和 pView->m_pDoc 不能为 nullptr\n"); return nullptr; } auto proxy = GetObjectProxy(pView, itemName); if (proxy) { return proxy->GetProperty(property).AllocSysString(); } else { return nullptr; } } /** * 设置 Item 属性 * * \param itemName item 名称,用于描述要操作的对象 * \param property 属性名称 * \return 属性值,全部使用字符串,通用 */ extern "C" __declspec(dllexport) void SetSigmaViewItemProperty(CSigmaView* pView, const LPCTSTR itemName, const LPCTSTR property, const LPCTSTR value) { if (pView == nullptr || pView->m_pDoc == nullptr) { TRACE("pView 和 pView->m_pDoc 不能为 nullptr\n"); return; } auto proxy = GetObjectProxy(pView, itemName); if (proxy) { proxy->SetProperty(property, value); } } //获取两个区域的相交区域 static NBase::CRect8 GetIntersectRect8(const NBase::CRect8& r1, const NBase::CRect8& r2) { // 计算相交区域 CRect8 out; out.left = std::max(r1.left, r2.left); out.top = (std::min)(r1.top, r2.top); out.right = (std::min)(r1.right, r2.right); out.bottom = std::max(r1.bottom, r2.bottom); // 检查交集是否有效 if (out.left <= out.right && out.top >= out.bottom) { return out; } // 无交集 return CRect8(0, 0, 0, 0); } static bool IsRectInside(const NBase::CRect8& r1, const NBase::CRect8& r2) { // 检查 r1 是否有效(可选,防止 r1 本身就是错误的矩形) if (r1.left > r1.right || r1.top < r1.bottom) { return false; } // 包含判断逻辑 (Y轴向上坐标系) // r1 的左边界 >= r2 的左边界 // r1 的右边界 <= r2 的右边界 // r1 的下边界 >= r2 的下边界 (因为是Y轴向上,内部的底边应该比外部的底边高) // r1 的上边界 <= r2 的上边界 (因为是Y轴向上,内部的顶边应该比外部的顶边低) if (r1.left >= r2.left && r1.right <= r2.right && r1.bottom >= r2.bottom && r1.top <= r2.top) { return true; } return false; } typedef void(__stdcall* MapDownloadProgressCallback)(int done, int total); /** * 下载地图 * * \param zoom 层级 * \param urlStr 地图地址 * \param borderLayer 地图指定边界 * \param dirPath 下载到本地的瓦片路径 * \param strPath 最终合并的瓦片路径 * \return MapViewLayer */ #include #include #include static std::future g_future; // 保存任务结果 static std::shared_ptr g_maplayer; // 全局保存,防止销毁 extern "C" __declspec(dllexport) MapViewLayer * DownloadSigmaViewItemMapView(CSigmaView* pView, int zoom, const wchar_t* urlStr, const wchar_t* borderLayer, const wchar_t* dirPath, const wchar_t* strPath, int type, MapDownloadProgressCallback progressCallback) { if (pView == nullptr || pView->m_pDoc == nullptr) { TRACE("pView 和 pView->m_pDoc 不能为 nullptr\n"); return nullptr; } CString mapUrl = CString(urlStr); CString mapImageDir = CString(dirPath); CString imagePath = CString(strPath); CXy* pXyCurrent = pView->m_pDoc->GetDraw(); //显示窗口范围 CRect8 rect1; CRect r1 = pView->GetClientRect(); rect1 = pView->m_pDoc->m_xyDC.GetReal(r1); NBase::CRect8 rect(1e100, -1e100, -1e100, 1e100); CString strLayer = CString(borderLayer); if (!strLayer.IsEmpty()) { CPositionList list; if (pXyCurrent->GetElement(strLayer, list) > 0) { for (POSITION pos = list.GetHeadPosition(); pos != NULL; list.GetNext(pos)) { POSITION pt = list.GetAt(pos); COne* pOne = pXyCurrent->GetAt(pt); if (pOne->GetType() == DOUBLEFOX_CURVE) { pOne->GetRange(rect); break; } } } } if (strLayer.IsEmpty() || (rect.left == 1e100)) { CMesh* pMesh = GetMesh(pView); if (pMesh != nullptr) { rect = pMesh->GetRect(); } else { rect = pXyCurrent->m_range; } } rect = GetIntersectRect8(rect, rect1); bool isGaodeTarget = false; if (type == 1) { //gcj02 isGaodeTarget = true; } g_maplayer = std::make_shared(); if (!g_maplayer->MapProjection(pXyCurrent, rect, isGaodeTarget)) return nullptr; // 异步执行下载任务 g_future = std::async(std::launch::async, [=]() { return g_maplayer->SaveTDTMapCroppedParallel( zoom, mapUrl, mapImageDir, imagePath, 12, progressCallback ); }); return g_maplayer.get(); } extern "C" __declspec(dllexport) bool IsSigmaViewMapView(CSigmaView* pView, const wchar_t* borderLayer) { if (pView == nullptr || pView->m_pDoc == nullptr) { TRACE("pView 和 pView->m_pDoc 不能为 nullptr\n"); return false; } CXy* pXyCurrent = pView->m_pDoc->GetDraw(); //显示窗口范围 CRect8 rect1; CRect r1 = pView->GetClientRect(); rect1 = pView->m_pDoc->m_xyDC.GetReal(r1); NBase::CRect8 rect(1e100, -1e100, -1e100, 1e100); CString strLayer = CString(borderLayer); if (!strLayer.IsEmpty()) { CPositionList list; if (pXyCurrent->GetElement(strLayer, list) > 0) { for (POSITION pos = list.GetHeadPosition(); pos != NULL; list.GetNext(pos)) { POSITION pt = list.GetAt(pos); COne* pOne = pXyCurrent->GetAt(pt); if (pOne->GetType() == DOUBLEFOX_CURVE) { pOne->GetRange(rect); break; } } } } if (strLayer.IsEmpty() || (rect.left == 1e100)) { CMesh* pMesh = GetMesh(pView); if (pMesh != nullptr) { rect = pMesh->GetRect(); } else { rect = pXyCurrent->m_range; } } return IsRectInside(rect, rect1); } /** * 插入地图 * * \param borderLayer 地图指定边界 * \param strPath 最终合并的瓦片路径 * \return */ extern "C" __declspec(dllexport) bool AddSigmaViewItemMapImage(CSigmaView* pView, const wchar_t* borderLayer, const wchar_t* strPath) { if (pView == nullptr || pView->m_pDoc == nullptr) { TRACE("pView 和 pView->m_pDoc 不能为 nullptr\n"); return false; } CString imagePath = CString(strPath); CXy* pXyCurrent = pView->m_pDoc->GetDraw(); //显示窗口范围 CRect8 rect1; CRect r1 = pView->GetClientRect(); rect1 = pView->m_pDoc->m_xyDC.GetReal(r1); NBase::CRect8 rect(1e100, -1e100, -1e100, 1e100); CString strLayer = CString(borderLayer); if (!strLayer.IsEmpty()) { CPositionList list; if (pXyCurrent->GetElement(strLayer, list) > 0) { for (POSITION pos = list.GetHeadPosition(); pos != NULL; list.GetNext(pos)) { POSITION pt = list.GetAt(pos); COne* pOne = pXyCurrent->GetAt(pt); if (pOne->GetType() == DOUBLEFOX_CURVE) { pOne->GetRange(rect); break; } } } } if (strLayer.IsEmpty() || (rect.left == 1e100)) { CMesh* pMesh = GetMesh(pView); if (pMesh != nullptr) { rect = pMesh->GetRect(); } else { rect = pXyCurrent->m_range; } } rect = GetIntersectRect8(rect, rect1); //处理完成后 将图片插入 CImageInsert* pImage = new CImageInsert(); if (!pImage->LoadImage(imagePath)) { delete pImage; return false; } pImage->SetRect(rect); POSITION pos = pXyCurrent->AddElement(pImage, DOUBLEFOX_IMAGE); COne* pOne = pXyCurrent->GetAt(pos); CLayer* pLayer = pXyCurrent->FindAddLayer("卫星地图"); pOne->SetLayer(pLayer); //最下显示 pXyCurrent->MoveToBack(pos); return true; } /** * 插入地图 * * \param borderLayer 地图指定边界 * \param strPath 最终合并的瓦片路径 * \return */ extern "C" __declspec(dllexport) void StopDownloadMaplayer(MapViewLayer *pMap) { if (pMap == nullptr) return; pMap->StopTask(); }