#include "StdAfx.h" #include "SigmaView.h" #include "itemmesh.h" #include "ItemSelect.h" struct StatisticsGraph { CHistogramStat * pStat; CMesh * pMesh; CItemMesh * pItemMesh; CRect graphOutRect; }; wchar_t * AsciiToUnicodeChar(const char * str); char* UnicodeToAscii(const wchar_t * str); static void InitStatisticsGraph(StatisticsGraph * statisticsGraph); static CItemMesh * GetItemMesh(CSigmaView * pView) { if (pView == NULL) return 0; CItem * pItem = pView->GetItem(); if (pItem == NULL) return NULL; CItemMesh * itemMesh = dynamic_cast(pItem); return itemMesh; } extern "C" __declspec(dllexport) bool SurfaceGetInfo(CSigmaView* pView, POSITION elementPtr , int& numX, int& numY , double& dLocationX, double& dLocationY , double& dDeltX, double& dDeltY , double& maxX, double& maxY) { COne * pOne = pView->m_pDoc->GetDraw()->GetAt(elementPtr); if (pOne == 0) return false; CMesh* pValue = (CMesh*)pOne->GetValue(); CGrid* pGrid = pValue->GetMesh(); numX = pGrid->xnum(); numY = pGrid->ynum(); dLocationX = pGrid->xmin(); dLocationY = pGrid->ymin(); dDeltX = pGrid->dx(); dDeltY = pGrid->dy(); maxX = pGrid->xmax(); maxY = pGrid->ymax(); return true; } extern "C" __declspec(dllexport) bool SurfaceGetImageInfo(CSigmaView* pView, POSITION elementPtr , int& numX, int& numY , double& dLocationX, double& dLocationY , double& dDeltX, double& dDeltY , double& maxX, double& maxY) { COne * pOne = pView->m_pDoc->GetDraw()->GetAt(elementPtr); if (pOne == 0) return false; CImageInsert* pValue = (CImageInsert*)pOne->GetValue(); CRect8 range(1e100, -1e100, -1e100, 1e100); pValue->GetRange(range); numX = pValue->m_pImage->GetWidth(); numY = pValue->m_pImage->GetHeight(); dLocationX = range.left; dLocationY = range.bottom; dDeltX = 0; dDeltY = 0; maxX = range.right; maxY = range.top; return true; } extern "C" __declspec(dllexport) bool SurfaceGetInfoDefault(CSigmaView* pView , int& numX, int& numY , double& dLocationX, double& dLocationY , double& dDeltX, double& dDeltY , double& maxX, double& maxY) { CPositionList lstMesh; int nCount = pView->m_pDoc->m_pXy->GetElement(DOUBLEFOX_MESH, lstMesh, TRUE); if (nCount < 1 || lstMesh.IsEmpty()) { return false; } POSITION posMesh = nullptr; posMesh = lstMesh.GetHeadPosition(); if (posMesh == nullptr) { return false; } POSITION pt = lstMesh.GetNext(posMesh); CMesh* pMesh = (CMesh*)(pView->m_pDoc->m_pXy->GetAtValue(pt)); return SurfaceGetInfo(pView, pt, numX, numY, dLocationX, dLocationY, dDeltX, dDeltY, maxX, maxY); } /* extern "C" __declspec(dllexport) void SurfaceSaveAs(CSigmaView* pView, LPCTSTR filePath,int index, POSITION elementPtr) { CItemMesh * itemMesh = GetItemMesh(pView, elementPtr); if (itemMesh == NULL) return; COne* pOne = (COne*)(pView->m_pDoc->GetDraw()->GetAt(elementPtr)); itemMesh->SaveAs(pOne,filePath,index); } */ extern "C" __declspec(dllexport) void SurfaceSaveAs(CSigmaView* pView, LPCTSTR filePath, int index, POSITION elementPtr) { COne * pOne = pView->m_pDoc->GetDraw()->GetAt(elementPtr); if (pOne == 0) return ; CItemMesh itemMesh(pView->m_pDoc); itemMesh.SaveAs(pOne, filePath, index); } extern "C" __declspec(dllexport) void SaveDataPointOnly(CSigmaView* pView,LPCTSTR filePath, POSITION elementPtr) { COne * pOne = pView->m_pDoc->GetDraw()->GetAt(elementPtr); if (pOne == 0) return; CItemMesh itemMesh(pView->m_pDoc); itemMesh.SaveAsOnlyData(pOne, filePath); } extern "C" __declspec(dllexport) void CreateContour(CSigmaView* pView) { CItemMesh * itemMesh = new CItemMesh(pView->m_pDoc); COne* pOne = pView->GetSelectedOne(DOUBLEFOX_MESH); itemMesh->CreateContour(pOne, nullptr); } extern "C" __declspec(dllexport) int Sigma_GetInfoStringForCreatingContour(CSigmaView * pView, wchar_t ** infoStrAddress) { COne* pOne = pView->GetSelectedOne(DOUBLEFOX_MESH); if (pOne == 0) return -1; CMesh* pValue = (CMesh*)pOne->GetValue(); CSize8 zrange; zrange.SetSize(0, 0); pValue->GetM(zrange.cx, zrange.cy); double contourStep = (zrange.cy - zrange.cx) / 20; contourStep = AfxGetPublicFunction()->ContourStep(contourStep); CString infoStr; infoStr.Format("%.8lf;5;%.8lf;%.8lf;Layer:\\Contour\\Mark;Layer:\\Contour\\Other", contourStep, zrange.cx, zrange.cy); *infoStrAddress = AsciiToUnicodeChar(infoStr.GetBuffer()); return (int)wcslen(*infoStrAddress); } extern "C" __declspec(dllexport) bool GetMeshPointValue(CSigmaView* pView, double ptX, double ptY, double& ptZ) { CPositionList lstMesh; int nCount = pView->m_pDoc->m_pXy->GetElement(DOUBLEFOX_MESH, lstMesh, TRUE); if (nCount < 1 || lstMesh.IsEmpty()) { return false; } POSITION posMesh = nullptr; posMesh = lstMesh.GetHeadPosition(); if (posMesh == nullptr) { return false; } POSITION pt = lstMesh.GetNext(posMesh); CMesh* pMesh = (CMesh*)(pView->m_pDoc->m_pXy->GetAtValue(pt)); ptZ = pMesh->GetValue(ptX, ptY); if (pMesh->IsInRangeZ(ptZ)) { return true; } ptZ = -1E100; return false; } extern "C" __declspec(dllexport) void Sigma_ReleaseInfoStringForCreatingContour(void * pAddress) { delete pAddress; } extern "C" __declspec(dllexport) int Sigma_CreateContour(CSigmaView * pView, char * informationStringForCreatingContour) { if (informationStringForCreatingContour == 0) return -1; COne* pOne = pView->GetSelectedOne(DOUBLEFOX_MESH); if (pOne == 0) return -1; CItemMesh im(pView->m_pDoc); im.CreateContour(pOne, informationStringForCreatingContour); //char * pInfo = UnicodeToAscii(informationStringForCreatingContour); /* CItemMesh * itemMesh = new CItemMesh(pView->m_pDoc); COne* pOne = pView->GetSelectedOne(DOUBLEFOX_MESH); itemMesh->CreateContour(pView, pOne); */ return 1; } extern "C" __declspec(dllexport) int Sigma_SmoothSurface(CSigmaView * pView, double coefficient, int smoothNumber) { COne* pOne = pView->GetSelectedOne(DOUBLEFOX_MESH); if (pOne == 0) return -1; CItemMesh im(pView->m_pDoc); if (!im.GridSmooth(pOne, coefficient, smoothNumber)) { return -1; } return 1; } extern "C" __declspec(dllexport) void EditGridNode(CSigmaView* pView, HDC hdc, POSITION elementPtr) { //CItemMesh itemMesh(pView->m_pDoc); //itemMesh.SetPos(elementPtr); //itemMesh.EditNode(pView, pView->m_client); CItemMesh * pItemMesh = GetItemMesh(pView); if (pItemMesh == nullptr) return; if (pView->m_pDoc->m_pXy->GetElementType(elementPtr) != DOUBLEFOX_MESH) { return; } CDC *pDC = CDC::FromHandle(hdc); pItemMesh->SetPos(elementPtr); pItemMesh->EditNode(pView, pDC, pView->m_client); } extern "C" __declspec(dllexport) bool MeshFindNodeLocation(CSigmaView* pView, HDC hdc, int mouseX, int mouseY, int& locationX, int& locationY) { CItemMesh * pItemMesh = GetItemMesh(pView); if (pItemMesh == nullptr) false; CPoint point; point.x = mouseX; point.y = mouseY; CDC *pDC = CDC::FromHandle(hdc); bool bFind = pItemMesh->FindNodeLocation(pDC, point, locationX, locationY); return bFind; } extern "C" __declspec(dllexport) void MeshOnMouseMove(CSigmaView* pView, HDC hdcMem, POSITION elementPtr, int mouseX, int mouseY) { CItemMesh * pItemMesh = GetItemMesh(pView); if (pItemMesh != nullptr) { CPoint pt; pt.x = mouseX; pt.y = mouseY; CDC *pDC = CDC::FromHandle(hdcMem); pView->m_pDoc->GetDC().Create(pDC); pItemMesh->OnMouseMove(pDC, 0, pt); } } extern "C" __declspec(dllexport) bool GridPointNoExist(CSigmaView* pView, POSITION elementPtr, int mouseX, int mouseY) { CItemMesh * pItemMesh = GetItemMesh(pView); if (pItemMesh != nullptr) { CPoint pt; pt.x = mouseX; pt.y = mouseY; return pItemMesh->GridPointNoExist(0, pt); } return FALSE; } extern "C" __declspec(dllexport) int GetGridValue(CSigmaView* pView, POSITION elementPtr, int mouseX, int mouseY, BYTE* gridWndValue) { CItemMesh * pItemMesh = GetItemMesh(pView); if (pItemMesh != nullptr) { CPoint pt; pt.x = mouseX; pt.y = mouseY; CString strValue = pItemMesh->GetGridValue(0, pt); int nLen = strValue.GetLength(); memcpy(gridWndValue, strValue.GetBuffer(0), nLen); return nLen; } return 0; } extern "C" __declspec(dllexport) int SetZOfGridPoint(CSigmaView* pView, double z, int row, int column) { CItemMesh * pItemMesh = GetItemMesh(pView); if (pItemMesh == 0) return -1; if (pItemMesh->SetZOfGridPoint(z, row, column)) { return 1; } return -1; } extern "C" __declspec(dllexport) StatisticsGraph * StatisticsGraph_Create(CSigmaView * pView) { CHistogramStat * pStat = new CHistogramStat(); COne* pOne = pView->GetSelectedOne(DOUBLEFOX_MESH); if (pOne == 0) return 0; CMesh* pMesh = (CMesh*)pOne->GetValue(); StatisticsGraph * statisticsGraph = new StatisticsGraph(); statisticsGraph->pStat = pStat; statisticsGraph->pMesh = pMesh; statisticsGraph->pItemMesh = new CItemMesh(pView->m_pDoc); statisticsGraph->pItemMesh->Histogram(); statisticsGraph->pItemMesh->SetPos(pView->GetSelectedOnePosition(DOUBLEFOX_MESH)); CRect rect(0, 0, 300, 300); statisticsGraph->graphOutRect = rect; InitStatisticsGraph(statisticsGraph); return statisticsGraph; } extern "C" __declspec(dllexport) void StatisticsGraph_Release(StatisticsGraph * graph) { if (graph != 0) delete graph; } extern "C" __declspec(dllexport) void StatisticsGraph_Draw(CSigmaView * pView, StatisticsGraph * graph, HDC hdc, int graphWidth, int graphHeight) { if (graph == 0) return; CDC * pDC = CDC::FromHandle(hdc); if (pDC == nullptr) return; COne* pOne = pView->GetSelectedOne(DOUBLEFOX_MESH); if (pOne == 0) return; CMesh* pMesh = (CMesh*)pOne->GetValue(); CRect rt(0, 0, graphWidth, graphHeight); CBrush brush; COLORREF white = RGB(255, 255, 255); brush.CreateSolidBrush(white); pDC->FillRect(&rt, &brush); graph->graphOutRect = rt; InitStatisticsGraph(graph); graph->pStat->SetPenWidth(2); graph->pStat->Draw(pDC, &(pMesh->color), rt); // &graph->pMesh->color //CDC * pDCDrawer = CDC::FromHandle(hdcDrawer); //pView->m_pDoc->m_xyDC.Create(pDCDrawer); //wrapper->pItemMesh->SetHistogramRange(-1562.89920, -1547.6952339619); //wrapper->pItemMesh->OnDraw(&pView->m_pDoc->m_xyDC); } extern "C" __declspec(dllexport) void StatisticsGraph_DrawRangeForMesh(CSigmaView * pView, StatisticsGraph * graph, HDC hdcDrawer, double zMin, double zMax) { CDC * pDCDrawer = CDC::FromHandle(hdcDrawer); pView->m_pDoc->m_xyDC.Create(pDCDrawer); graph->pItemMesh->SetHistogramRange(zMin, zMax); graph->pItemMesh->OnDraw(&pView->m_pDoc->m_xyDC); } extern "C" __declspec(dllexport) int StatisticsGraph_GetSelectedRange(StatisticsGraph * graph, int left, int right, double * z1, double * z2) { if (left < 0 || right < 0 || graph == 0) { return -1; } if (left > right) { int dt = left; left = right; right = dt; } int m_num = graph->pStat->GetSize(); double* m_pz = graph->pStat->m_pz; int x = left/2; int y = right/2; if (x < 0) x = 0; if (x > m_num - 1) x = m_num - 1; if (y < 0) y = 0; if (y > m_num - 1) y = m_num - 1; double delt = m_pz[1] - m_pz[0]; *z1 = m_pz[x]; *z2 = m_pz[y]; if (left % 2 > 0) *z1 += delt * 0.5; if (right % 2 > 0) *z2 += delt * 0.5; return 1; } extern "C" __declspec(dllexport) void StatisticsGraph_CalculateGraphRange(StatisticsGraph * graph, double z1In, double z2In, int * leftOut, int * rightOut) { if (z1In > z2In) { double t = z1In; z1In = z2In; z2In = t; } double zmin = graph->pStat->zmin; double zmax = graph->pStat->zmax; int m_num = graph->pStat->GetSize(); double* m_pz = graph->pStat->m_pz; double delt = m_pz[1] - m_pz[0]; //z值范围 int dz = (int)((z1In - zmin) / delt); *leftOut = dz * 2 + int((z1In - zmin) / delt - dz + 0.5); dz = (int)((z2In - zmin) / delt); *rightOut = dz * 2 + int((z2In - zmin) / delt - dz + 0.5); } extern "C" __declspec(dllexport) int StatisticsGraph_DeleteRange(StatisticsGraph * graph, int left, int right) { if (graph == 0) return -1; double z1 = 0; double z2 = 0; if (StatisticsGraph_GetSelectedRange(graph, left, right, &z1, &z2) == -1) return -1; graph->pItemMesh->SetHistogramRange(z1, z2); if (graph->pItemMesh->DeleteSelected() <= 0) return 0; if (graph->pStat->m_pn == NULL) return 0; //graph->pItemMesh->SetHistogramRange(z1, z2); int i = graph->pStat->PositionValueIndex(z1); int j = graph->pStat->PositionValueIndex(z2); if (i < 0) i = 0; if (j < 0) j = 0; if (j > graph->pStat->m_num - 1) j = graph->pStat->m_num - 1; for (int n = i; n <= j; n++) graph->pStat->m_pn[n] = 0; return 1; } extern "C" __declspec(dllexport) int StatisticsGraph_GetRange(StatisticsGraph * graph, double * xMinOut, double * xMaxOut, double * yMinOut, double * yMaxOut, int * pointerCount) { if (graph == 0) return -1; *xMinOut = graph->pStat->zmin; *xMaxOut = graph->pStat->zmax; *yMinOut = 0; *yMaxOut = graph->pStat->GetMaxStatCount(); *pointerCount = graph->pStat->GetSize(); return 1; } extern "C" __declspec(dllexport) int StatisticsGraph_GetZValue(StatisticsGraph * graph, int index, double * v) { if (graph == 0) return -1; *v = graph->pStat->m_pz[index]; return 1; } extern "C" __declspec(dllexport) void StatisticsGraph_SetZValueOfNodeSelected(StatisticsGraph * graph, double v) { graph->pItemMesh->SetZValueOfNodeSelected(v); InitStatisticsGraph(graph); } extern "C" __declspec(dllexport) void StatisticsGraph_GetAreaAndValueForSelected(StatisticsGraph * graph, double minZ, double maxZ, double * areaOut, double * volumeOut) { graph->pItemMesh->GetAreaAndValueForSelected(minZ, maxZ, areaOut, volumeOut); } static void InitStatisticsValue(CMesh* pMesh, CHistogramStat * pStat) { long numx, numy; int i, j; pMesh->GetNumber(numx, numy); pStat->ClearStatState(); #pragma omp parallel for for (i = 0; i < numx; i++) { for (j = 0; j < numy; j++) { double z = pMesh->GetValue(i, j); // 性能瓶颈之一 if (!pMesh->IsInRangeZ(z)) continue; #pragma omp critical { pStat->StatAdd(z); // 性能瓶颈之二,不知道能不能并行,先保守一点,认为是不能并行的 } } } } static void InitStatisticsGraph(StatisticsGraph * statisticsGraph) { if (statisticsGraph == NULL || statisticsGraph->pMesh == NULL) return; double zmin = 0; double zmax = 0; statisticsGraph->pMesh->GetM(zmin, zmax); statisticsGraph->pStat->SetValueRange(zmin, zmax); int num = statisticsGraph->graphOutRect.Width() / 2 - 1; if (num <= 1) num = 2; if (!statisticsGraph->pStat->CreateStat(zmin, zmax, num)) return; InitStatisticsValue(statisticsGraph->pMesh, statisticsGraph->pStat); }