You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1531 lines
35 KiB
C++

1 month ago
#include "Stdafx.h"
#include "SigmaView.h"
#include "ItemCurveArc.h"
#include "ItemCurveEdit.h"
#include "ItemSelect.h"
#include "ItemCurveProcess.h"
#include "ItemCurveEditDeleteMulNodes.h"
1 month ago
#include "ActionAddItem.h"
1 month ago
#include "ActionListItem.h"
1 month ago
#include "ActionBackupItem.h"
1 month ago
#include "BufferAgency.h"
#include "ItemLinkCurve.h"
#include "TinyXml/tinyxml.h"
#include "PolygonCombiner.h"
1 month ago
#include "BoundaryDetection.h"
#include "GapDetection.h"
#include "OverlapDetection.h"
#include "ActionComboItem.h"
#include "ActionDeleteLayerItem.h"
#include "Legend.h"
#include "PolygonSnapper.h"
#include "ActionComboItem.h"
1 month ago
#pragma pack(1)
struct CurveNode
{
double x;
double y;
double z;
double len;
double realLen;
double angle;
};
#pragma pack()
wchar_t * AsciiToUnicodeChar(const char * str);
static CItemCurve * GetItemCurveFromView(CSigmaView * pView);
static CItemCurveMerge * GetMergeCurveFromView(CSigmaView * pView);
static CItemCurveEdit * GetItemCurveEdit(CSigmaView * pView);
static CCurveEx * GetCurveEx(CSigmaView * pView);
static double _GetAngle(double x1, double y1, double x2, double y2);
static bool getNodeFromCurve(CCurveEx* pcIn, CurveNode * nodeOut, int nodeIndex);
static CItemCurveEditDeleteMulNodes * GetEditDeleteMulNodesFromView(CSigmaView * pView);
1 month ago
static std::vector<CCurveEx*> ConverToVector(CXy* pXy, CPositionList& positions);
static std::optional<CPoint2D> GetBoundsCenter(const CCurveEx* pCurve);
static POSITION AddTextMarker(CXy* pXy, CLayer* pLayer, double centerX, double centerY, const char* text);
static std::unique_ptr<CActionBackupItem> CloseCurve(CSigmaView* pView, const std::vector<CString>& layers);
static std::unique_ptr<CActionBackupItem> ResolveSnap(CSigmaView* pView, const std::vector<CString>& layers, double gap, double degrees, double snapRadius, double maxExtension);
1 month ago
extern "C" __declspec(dllexport)
int AutoCloseCurve(CSigmaView * pView)
{
CItemCurveMerge * pItem = GetMergeCurveFromView(pView);
if (pItem == NULL)
return -1;
pItem->AutoClose();
return 1;
}
extern "C" __declspec(dllexport)
int EndCurve(CSigmaView * pView)
{
CItemCurveMerge * pItem = GetMergeCurveFromView(pView);
if (pItem == NULL)
return -1;
pItem->EndCurve();
return 1;
}
extern "C" __declspec(dllexport)
int DrawNextCurve(CSigmaView * pView)
{
CItemCurveMerge * pItem = GetMergeCurveFromView(pView);
if (pItem == NULL)
return -1;
pItem->NextCurve();
return 1;
}
extern "C" __declspec(dllexport)
int ChangeCurveTypeForDrawing(CSigmaView * pView, LPCTSTR curveType, HDC hdc)
{
//CItemCurveMerge * pItem = GetMergeCurveFromView(pView);
CItemCurve* pItem = GetItemCurveFromView(pView);
if (pItem == NULL)
return -1;
CDC * pDC = CDC::FromHandle(hdc);
if (_strcmpi("line", curveType) == 0)
{
pItem->SetCurveState(CURVE_STATE_LINE, pDC);
}
else if (_strcmpi("arc", curveType) == 0)
{
pItem->SetCurveState(CURVE_STATE_ARC, pDC);
}
else if (_strcmpi("spline", curveType) == 0)
{
pItem->SetCurveState(CURVE_STATE_SPLINE, pDC);
}
else if (_strcmpi("RightAngle", curveType) == 0)
{
pItem->SetCurveState(CURVE_STATE_ANGLE, pDC);
}
1 month ago
else if (_strcmpi("DragSegment", curveType) == 0)
{
pItem->SetCurveState(CURVE_STATE_DRAG_SEGMENT, pDC);
}
1 month ago
else if (_strcmpi("merage", curveType) == 0)
{
pItem->SetCurveState(CURVE_STATE_MERGE, pDC);
}
else if (_strcmpi("drawing", curveType) == 0)
{
pItem->SetCurveState(CURVE_STATE_DRAWING, pDC);
}
else
{
return -1;
}
CItemCurveEditDeleteMulNodes* itemEdit = GetEditDeleteMulNodesFromView(pView);
if (itemEdit != nullptr) {
itemEdit->GetMarkCurve();
}
return 1;
}
extern "C" __declspec(dllexport)
int CancelCurve(CSigmaView * pView)
{
CItemCurveMerge * pItem = GetMergeCurveFromView(pView);
if (pItem == NULL)
return -1;
pItem->OnCancel();
return 1;
}
extern "C" __declspec(dllexport)
int CurveCancelAll(CSigmaView * pView)
{
//CItemCurveMerge * pItem = GetMergeCurveFromView(pView);
//CItemCurveEditDeleteMulNodes * pItem = GetEditDeleteMulNodesFromView(pView);
//CItemCurveEdit * pItem = GetItemCurveEdit(pView);
CItem * pItem = pView->m_pDoc->GetItem();
if (pItem == NULL)
return -1;
CItemCurveEdit * pItemSelect = dynamic_cast<CItemCurveEdit *>(pItem);
if (pItemSelect == NULL)
return -1;
pItemSelect->CancelAll();
return 1;
}
extern "C" __declspec(dllexport)
int ChangeCurveMergeState(CSigmaView * pView)
{
CItemCurveMerge * pItem = GetMergeCurveFromView(pView);
if (pItem == NULL)
return -1;
pItem->ChangeMergeState();
return 1;
}
//<2F><><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD><DFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
extern "C" __declspec(dllexport)
int CurveSelected_GetCountOfCoordinate(CSigmaView * pView)
{
CCurveEx * curve = GetCurveEx(pView);
if (curve == NULL)
return -1;
return curve->num;
}
extern "C" __declspec(dllexport)
bool GetXy_ProjectionIsEmpty(CSigmaView* pView)
{
CXy* xy = pView->m_pDoc->m_pXy;
if (xy == NULL)
return true;
if (xy->GetProjection().IsEmpty())
{
return true;
}
else
{
return false;
}
}
extern "C" __declspec(dllexport)
void CurveXY_EXChangeLatLong(CSigmaView * pView, double &x, double &y)
{
CXy* xy = pView->m_pDoc->m_pXy;
if (xy == NULL)
return;
CProjection proj = xy->m_ExchangeXYZ;
CExchangeXYZ exyz;
exyz.SetProjection(&proj);
exyz.ToBL_D(x, y);
}
extern "C" __declspec(dllexport)
int CurveSelected_GetCurveNode(CSigmaView * pView, int nodeIndex, CurveNode * nodeOut)
{
if (nodeOut == NULL)
return -1;
CCurveEx* pc = GetCurveEx(pView);
if (pc == NULL)
return -1;
if (!getNodeFromCurve(pc, nodeOut, nodeIndex))
return -1;
return 1;
}
extern "C" __declspec(dllexport)
int CurveSelected_SaveNodeToCSVFile(CSigmaView * pView, LPCTSTR fileFullPath)
{
CItemCurveEdit * pItemCurvEdit = GetItemCurveEdit(pView);
if (pItemCurvEdit == NULL)
return -1;
CCurveEx* pc = (CCurveEx*)pView->m_pDoc->GetDraw()->GetAtValue(pItemCurvEdit->GetPos());
if (pc == NULL)
return -1;
FILE* fw = NULL;
fw = fopen(fileFullPath, "wt");
if (fw == NULL)
return -1;
//<2F><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>ͷ
if (fputs("X, Y, Z, L, ʵ<>ʳ<EFBFBD><CAB3><EFBFBD>, <20>Ƕ<EFBFBD>\n", fw) == EOF)
goto FAIL;
CurveNode node;
for (int i = 0; i < pc->num; i++)
{
memset(&node, 0, sizeof(CurveNode));
if (!getNodeFromCurve(pc, &node, i))
goto FAIL;
fprintf(fw, "%.6f,%.6f,%.6f,%.6f,%.6f,%.6f\n", node.x, node.y, node.z, node.len, node.realLen, node.angle);
}
fclose(fw);
return 1;
FAIL:
fclose(fw);
return -1;
}
extern "C" __declspec(dllexport)
int CurveEditNode_Draw(CSigmaView* pView, HDC hdc)
{
CItemCurveEditDeleteMulNodes * pItem = GetEditDeleteMulNodesFromView(pView);
if (pItem == NULL)
return -1;
CDC *pDC = CDC::FromHandle(hdc);
pView->SetScreenDC(pDC);
pItem->Draw(pDC);
return 1;
}
extern "C" __declspec(dllexport)
void CurveEditNode_EnableMulDelete(CSigmaView* pView, bool enable)
{
CItemCurveEditDeleteMulNodes * pItem = GetEditDeleteMulNodesFromView(pView);
if (pItem == NULL)
return;
pItem->EnableMulDelete(enable);
}
extern "C" __declspec(dllexport)
int CurveEditNode_EreaseHandles(CSigmaView* pView, HDC hdc)
{
CItemCurveEditDeleteMulNodes * pItem = GetEditDeleteMulNodesFromView(pView);
if (pItem == NULL)
return -1;
CDC *pDC = CDC::FromHandle(hdc);
pView->SetScreenDC(pDC);
pItem->EreaseHandles(pDC);
return 1;
}
extern "C" __declspec(dllexport)
int CurveEditNode_GetNodeSelected(CSigmaView* pView, int mouseX, int mouseY)
{
CItemCurveEditDeleteMulNodes * pItem = GetEditDeleteMulNodesFromView(pView);
if (pItem == NULL)
return -1;
CPoint pt(mouseX, mouseY);
return pItem->HitTestHandle(pt);
}
extern "C" __declspec(dllexport)
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵĽڵ<C4BD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>-1
int CurveEditNode_AddNode(CSigmaView* pView, int mouseX, int mouseY)
{
CItemCurveEditDeleteMulNodes * pItem = GetEditDeleteMulNodesFromView(pView);
if (pItem == NULL)
return -1;
CPoint pt(mouseX, mouseY);
return pItem->AddHandle(pt);
}
extern "C" __declspec(dllexport)
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵĽڵ<C4BD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>-1
int CurveEditNode_DeleteNode(CSigmaView* pView, int mouseX, int mouseY)
{
CItemCurveEditDeleteMulNodes * pItem = GetEditDeleteMulNodesFromView(pView);
if (pItem == NULL)
return -1;
if (pItem->GetHandleIndex() < 0)
return -1;
pItem->DeleteHandle(pItem->GetHandleIndex());
return 1;
}
extern "C" __declspec(dllexport)
//-1<><31><EFBFBD><EFBFBD> 1 Ĭ<>Ϲ<EFBFBD><CFB9><EFBFBD> 2 <20><><EFBFBD>ӹ<EFBFBD><D3B9><EFBFBD> 3 <20>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD><EFBFBD>
int CurveEditNode_GetCursorTpye(CSigmaView* pView, int mouseX, int mouseY)
{
CItemCurveEditDeleteMulNodes * pItem = GetEditDeleteMulNodesFromView(pView);
if (pItem == NULL)
return -1;
CPoint pt(mouseX, mouseY);
int index = pItem->HitTestHandle(pt);
if (index < 0)
{
if (pItem->IsCanAddHandle(pt))//<2F><><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD><EFBFBD><EFBFBD>
{
return 2;
}
return 1;
}
return 3;
}
extern "C" __declspec(dllexport)
int CurveEditNode_GetCountOfNode(CSigmaView * pView)
{
CItemCurveEditDeleteMulNodes * pItem = GetEditDeleteMulNodesFromView(pView);
if (pItem == NULL)
return -1;
return pItem->GetNumberOfNode();
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ
extern "C" __declspec(dllexport)
int DrawerCurveConnect(CSigmaView* pView, LPCTSTR layerName, bool deleteOriginalCurves) {
CItemSelect * itemSelect = pView->m_pDoc->GetSelectItem();
if (itemSelect == 0)
return 0;
CItemCurveProcess curveProcess(pView->m_pDoc);
CString strLayerName(layerName);
return curveProcess.PolygonConnect(itemSelect->m_selection, strLayerName, deleteOriginalCurves);
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߽ڵ<DFBD>
extern "C" __declspec(dllexport)
int Curve_IncreaseDensityNode(CSigmaView * pView, int mode, double step, int rounding)
{
if (mode != 0 && mode != 1)
return -1;
if (rounding != 0 && rounding != 1)
return -1;
if (step <= 0)
return -1;
if (pView == 0)
return -1;
if (pView->m_pDoc == 0)
return -1;
//DrawTooolCurveDensityNode<64><65> <20><>item<65><6D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΪITEM_SELECT <20>ڵ<EFBFBD><DAB5>ô˺<C3B4><CBBA><EFBFBD>ʱ <20><>δ<EFBFBD>л<EFBFBD>Item <20><><EFBFBD>Ե<EFBFBD>ǰ<EFBFBD><C7B0>Item<65><6D><EFBFBD><EFBFBD>CItemSelect
CItemSelect * itemSelect = pView->m_pDoc->GetSelectItem();
if (itemSelect == 0)
return -1;
CItemCurveProcess curveProcess(pView->m_pDoc);
if (curveProcess.NodeEncrypt(mode, step, rounding == 1, itemSelect->m_selection))
return 1;
return -1;
}
//ȥ<><C8A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľڵ<C4BD>
extern "C" __declspec(dllexport)
int Curve_Redundance(CSigmaView * pView, double tolerance)
{
if (tolerance < 0)
return -1;
if (pView == 0)
return -1;
if (pView->m_pDoc == 0)
return -1;
//DrawTooolCurveDensityNode<64><65> <20><>item<65><6D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΪITEM_SELECT <20>ڵ<EFBFBD><DAB5>ô˺<C3B4><CBBA><EFBFBD>ʱ <20><>δ<EFBFBD>л<EFBFBD>Item <20><><EFBFBD>Ե<EFBFBD>ǰ<EFBFBD><C7B0>Item<65><6D><EFBFBD><EFBFBD>CItemSelect
CItemSelect * itemSelect = pView->m_pDoc->GetSelectItem();
if (itemSelect == 0)
return -1;
CItemCurveProcess curveProcess(pView->m_pDoc);
if (curveProcess.ToRedundant(tolerance, itemSelect->m_selection))
return 1;
return -1;
}
extern "C" __declspec(dllexport)
int Curve_ArcToCurve(CSigmaView * pView, double step)
{
CItemSelect * itemSelect = pView->m_pDoc->GetSelectItem();
if (itemSelect == 0)
return -1;
CItemCurveProcess curveProcess(pView->m_pDoc);
int num = curveProcess.ArcToCurve(itemSelect->m_selection, step);
if (num <= 0)
{
return -1;
}
return 1;
}
extern "C" __declspec(dllexport)
int Curve_Smooth(CSigmaView * pView, int mode, double step)
{
if (mode != 0 && mode != 1)
return -1;
if (pView == 0)
return -1;
if (pView->m_pDoc == 0)
return -1;
CItemSelect * itemSelect = pView->m_pDoc->GetSelectItem();
if (itemSelect == 0)
return -1;
CItemCurveProcess curveProcess(pView->m_pDoc);
if (curveProcess.SmoothCurve(mode, step, itemSelect->m_selection))
return 1;
return -1;
}
/// <20>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
extern "C" __declspec(dllexport)
int Curve_AutoJoin(CSigmaView * pView, double maxError, bool onlySameName) {
CItemCurveProcess itemCurveProcess(pView->m_pDoc);
return itemCurveProcess.AutoLinkCurve(maxError, onlySameName);
}
extern "C" __declspec(dllexport)
int Curve_SetName(CSigmaView * pView, LPCTSTR curveName)
{
if (pView == 0)
return -1;
if (pView->m_pDoc == 0)
return -1;
//DrawTooolCurveDensityNode<64><65> <20><>item<65><6D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΪITEM_SELECT <20>ڵ<EFBFBD><DAB5>ô˺<C3B4><CBBA><EFBFBD>ʱ <20><>ǰ<EFBFBD><C7B0>Item<65><6D><EFBFBD><EFBFBD>CItemSelect
CItemSelect * itemSelect = pView->m_pDoc->GetLastSelectItem();
if (itemSelect == 0)
return -1;
CItemCurveProcess curveProcess(pView->m_pDoc);
curveProcess.SetCurveName(curveName, itemSelect->m_selection);
return 1;
}
extern "C" __declspec(dllexport)
int Curve_GetCurvesOfEmptyName(CSigmaView * pView, BufferAgency * bufferOut)
{
bufferOut->buffer = nullptr;
bufferOut->len = 0;
if (pView == 0)
return -1;
if (pView->m_pDoc == 0)
return -1;
CItemSelect * itemSelect = pView->m_pDoc->GetSelectItem();
if (itemSelect == 0)
return -1;
CItemCurveProcess curveProcess(pView->m_pDoc);
std::string curvesStr = curveProcess.FindNameIsNull(itemSelect->m_selection);
if (curvesStr.empty())
return -1;
bufferOut->buffer = AsciiToUnicodeChar(curvesStr.c_str());
bufferOut->len = (int)wcslen(bufferOut->buffer);
return 1;
}
/**
* <EFBFBD><EFBFBD>ȡ<EFBFBD>ǶȺ;<EFBFBD><EFBFBD><EFBFBD>
*
* \param pView
* \return <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ؿ<EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>򷵻<EFBFBD><EFBFBD><EFBFBD> "," <EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>ǽǶȣ<EFBFBD><EFBFBD>ڶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
extern "C" __declspec(dllexport)
bool GetCurveAngleAndDistance(CSigmaView* pView, double *angle, double *distance)
{
if (pView == 0)
return false;
if (pView->m_pDoc == 0)
return false;
CItem * pItem = pView->GetItem();
if (pItem == NULL)
return false;
if (CItemCurve* pItemCurve = dynamic_cast<CItemCurve*>(pItem))
{
return pItemCurve->GetAngleAndDistance(*angle, *distance);
}
return false;
}
1 month ago
static std::vector<CCurveEx*> FilterCurves(CXy* pXy, const CString& layers)
{
assert(pXy != nullptr);
CXyElementFilter filter;
filter.addType(DOUBLEFOX_CURVE);
std::vector<CString> vec = SplitString(layers, _T(","));
for (const auto& layer : vec)
{
filter.addLayer(layer, false);
}
CPositionList select;
pXy->GetElement(filter, select);
return ConverToVector(pXy, select);
}
/**
* <EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD>ɾ<EFBFBD><EFBFBD><EFBFBD>ͻָ<EFBFBD>̫<EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD>ֵģ<EFBFBD>ֻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ã<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ط<EFBFBD>ʹ<EFBFBD>ÿ<EFBFBD><EFBFBD>ܳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* \param pView
* \param pItem
* \param layerName
*/
static void ClearLayer(CSigmaView* pView, CActionComboItem& pItem, const CString& layerName)
{
CXy* pXy = pView->m_pDoc->m_pXy;
CLayer* pLayer = pXy->FindLayer(layerName);
if (pLayer == nullptr)
{
return;
}
CPtrList layers;
layers.AddTail(pLayer);
NBase::CPositionList select;
int n = pXy->GetElement(layerName, select, FALSE, FALSE);
pItem.AddAction(new CActionLayerDeleteItem(pView->m_pDoc, select, layers));
CLayer* pCurrentLayer = pXy->GetCurrentLayer();
if (layers.Find(pCurrentLayer))
{
if (pXy->GetClassList()->GetLayerCount() == 0)
{
if (pXy->GetClassList()->GetCount() == 0)
pXy->InitLayerClass();
else
pXy->GetClassList()->GetHead()->FindAdd("0");
}
pXy->SetCurrentLayer(pXy->GetClassList()->GetHead()->GetHead());
}
}
/**
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD>պϼ<EFBFBD><EFBFBD><EFBFBD>
*
* \param pView
* \param layers <EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>
*/
extern "C" __declspec(dllexport)
void MineralRightsUnclosedDetection(CSigmaView* pView, const LPCTSTR layers)
{
if (pView == nullptr || pView->m_pDoc == nullptr || pView->m_pDoc->m_pXy == nullptr)
{
TRACE("pView <20><><EFBFBD><EFBFBD>Ϊ nullptr\n");
return;
}
if (pView->m_pDoc == nullptr || pView->m_pDoc->m_pXy == nullptr)
{
TRACE("ͼ<EFBFBD><EFBFBD><EFBFBD>\n");
return;
}
CXy* pXy = pView->m_pDoc->m_pXy;
std::unique_ptr<CActionComboItem> pItem = std::make_unique<CActionComboItem>(pView->m_pDoc, 0);
const CString layerName = _T("δ<EFBFBD>պ<EFBFBD>");
ClearLayer(pView, *pItem, layerName);
std::vector<CCurveEx*> curves = FilterCurves(pXy, layers);
BoundaryDetection boundaryDetection;
auto closeResult = boundaryDetection.CheckClosure(curves);
auto* pUnclosedLayer = pXy->FindAddLayer(layerName);
CPositionList positions;
for (auto& pair : closeResult)
{
if (!pair.isClosed)
{
COne* pOne = new COne();
double width = 10.0;
double height = 26.0;
CCurveEx* pCurve = pair.pCurve;
double startX = pCurve->x[0];
double startY = pCurve->y[0];
int lastIdx = pCurve->num - 1;
double endX = pCurve->x[lastIdx];
double endY = pCurve->y[lastIdx];
double midX = (startX + endX) / 2;
double midY = (startY + endY) / 2;
double textX = midX - (width / 2); // <20><><EFBFBD><EFBFBD> X λ<><CEBB>
double textY = midY + (height / 2); // <20><><EFBFBD><EFBFBD> Y λ<><CEBB>
POSITION pos = AddTextMarker(pXy, pUnclosedLayer, midX, midY, "-|-");
positions.AddTail(pos);
}
}
if (positions.GetCount() > 0)
{
pItem->AddAction(new CActionAddItem(pView->m_pDoc, IDS_STRING_ACTION_ADD, positions));
}
if (pItem->GetCount() > 0)
{
pView->m_pDoc->SetActionItem(pItem.release());
}
}
/**
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* \param pView
* \param layers <EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>
*/
extern "C" __declspec(dllexport)
void MineralRightsOverlapDetection(CSigmaView* pView, const LPCTSTR layers)
{
if (pView == nullptr || pView->m_pDoc == nullptr || pView->m_pDoc->m_pXy == nullptr)
{
TRACE("pView <20><><EFBFBD><EFBFBD>Ϊ nullptr\n");
return;
}
if (pView->m_pDoc == nullptr || pView->m_pDoc->m_pXy == nullptr)
{
TRACE("ͼ<EFBFBD><EFBFBD><EFBFBD>\n");
return;
}
CXy* pXy = pView->m_pDoc->m_pXy;
std::unique_ptr<CActionComboItem> pItem = std::make_unique<CActionComboItem>(pView->m_pDoc, 0);
const CString layerName = _T("<EFBFBD>");
ClearLayer(pView, *pItem, layerName);
std::vector<CCurveEx*> curves = FilterCurves(pXy, layers);
OverlapDetection overlapDetection;
auto overlaps = overlapDetection.DetectOverlap(curves);
auto* pOverlapLayer = pXy->FindAddLayer(layerName);
CPositionList positions;
for (auto&& overlap : overlaps)
{
auto centerPoint = GetBoundsCenter(overlap.pArea.get());
if (centerPoint)
{
POSITION pos = AddTextMarker(pXy, pOverlapLayer, centerPoint->x0, centerPoint->y0, "<EFBFBD><EFBFBD>|<7C><>");
positions.AddTail(pos);
}
}
if (positions.GetCount() > 0)
{
pItem->AddAction(new CActionAddItem(pView->m_pDoc, IDS_STRING_ACTION_ADD, positions));
}
if (pItem->GetCount() > 0)
{
pView->m_pDoc->SetActionItem(pItem.release());
}
}
/**
* <EFBFBD><EFBFBD><EFBFBD>߷<EFBFBD>϶<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* \param pView
* \param layers Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>
*/
extern "C" __declspec(dllexport)
void MineralRightsGapDetection(CSigmaView* pView, const LPCTSTR layers, double gap)
{
if (pView == nullptr || pView->m_pDoc == nullptr || pView->m_pDoc->m_pXy == nullptr)
{
TRACE("pView <20><><EFBFBD><EFBFBD>Ϊ nullptr\n");
return;
}
if (pView->m_pDoc == nullptr || pView->m_pDoc->m_pXy == nullptr)
{
TRACE("ͼ<EFBFBD><EFBFBD><EFBFBD>\n");
return;
}
CXy* pXy = pView->m_pDoc->m_pXy;
std::unique_ptr<CActionComboItem> pItem = std::make_unique<CActionComboItem>(pView->m_pDoc, 0);
const CString layerName = _T("<EFBFBD><EFBFBD>϶");
ClearLayer(pView, *pItem, layerName);
std::vector<CCurveEx*> curves = FilterCurves(pXy, layers);
GapDetection gapDetection;
gapDetection.SetGapValue(gap);
auto gaps = gapDetection.DetectGaps(curves);
auto* pGapLayer = pXy->FindAddLayer(layerName);
CPositionList positions;
for (auto&& gap : gaps)
{
auto centerPoint = GetBoundsCenter(gap.pArea.get());
if (centerPoint)
{
POSITION pos = AddTextMarker(pXy, pGapLayer, centerPoint->x0, centerPoint->y0, "<EFBFBD><EFBFBD>|<7C><>");
positions.AddTail(pos);
}
}
if (positions.GetCount() > 0)
{
pItem->AddAction(new CActionAddItem(pView->m_pDoc, IDS_STRING_ACTION_ADD, positions));
}
if (pItem->GetCount() > 0)
{
pView->m_pDoc->SetActionItem(pItem.release());
}
}
/**
* <EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><EFBFBD>޸<EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD>պϡ<EFBFBD>
*
* \param pView
* \param layers
*/
extern "C" __declspec(dllexport)
void MineralRightsAutoFix(CSigmaView* pView, const LPCTSTR layers, double gap, double degress, double snapRadius, double maxExtension)
{
CString layersStr(layers);
std::vector<CString> layersVec = SplitString(layersStr, _T(","));
std::unique_ptr<CActionBackupItem> pItem1 = CloseCurve(pView, layersVec);
std::unique_ptr<CActionBackupItem> pItem2 = ResolveSnap(pView, layersVec, gap, degress, snapRadius, maxExtension);
std::unique_ptr<CActionComboItem> pItem = std::make_unique<CActionComboItem>();
if (pItem1->GetCount() > 0)
{
pItem->AddAction(pItem1.release());
}
if (pItem2->GetCount() > 0)
{
pItem->AddAction(pItem2.release());
}
if (pItem->GetCount() > 0)
{
pView->m_pDoc->SetActionItem(pItem.release());
}
}
1 month ago
static void GetClosedCurves(CXy& xy, CPositionList& selection, CPositionList& closedCurves)
{
POSITION pos = selection.GetHeadPosition();
while (pos != nullptr)
{
POSITION prev = pos;
POSITION pt = selection.GetNext(pos);
COne* pOne = xy.GetAt(pt);
if (pOne != nullptr && pOne->GetType() == DOUBLEFOX_CURVE)
{
CCurveEx* pCurve = pOne->GetValueSafe<CCurveEx>();
if (pCurve->IsClosed())
{
closedCurves.AddTail(pt);
}
}
}
}
static void GroupCurves(CXy& xy,
CPositionList& curves,
std::vector<CCurveEx*>& left,
std::vector<CCurveEx*>& right)
{
int half = curves.GetCount() / 2;
POSITION pos = curves.GetHeadPosition();
while (pos != nullptr) {
POSITION pt = curves.GetNext(pos);
COne* pOne = xy.GetAt(pt);
assert(pOne != nullptr);
CCurveEx* pCurve = pOne->GetValueSafe<CCurveEx>();
if (left.size() < half) {
left.push_back(pCurve);
} else {
right.push_back(pCurve);
}
}
}
/**
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* \param pView pView
* \param booleanOp <EFBFBD>ϲ<EFBFBD><EFBFBD><EFBFBD>ʽ
* 0: // Difference
* 1: // Intersect
* 2: // Union
* 3: // XOR
* \return
*/
extern "C" __declspec(dllexport)
bool PolygonBooleanOperation(CSigmaView* pView, int booleanOp)
{
if (pView == nullptr)
{
TRACE("pView <20><><EFBFBD><EFBFBD>Ϊ nullptr\n");
return false;
}
if (booleanOp < 0 || booleanOp > 3)
{
TRACE("booleanOp <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> [0, 3] ֮<><D6AE>\n");
return false;
}
auto* pItem = pView->GetItem();
if (pItem == nullptr)
{
return false;
}
CItemSelect * pItemSelect = dynamic_cast<CItemSelect *>(pItem);
if (pItemSelect == nullptr)
{
TRACE("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n");
return false;
}
CXy* pXy = pView->m_pDoc->m_pXy;
CPositionList& selection = pItemSelect->m_selection;
if (selection.GetCount() < 2)
{
return false;
}
CPositionList closedCurves;
GetClosedCurves(*pXy, selection, closedCurves);
if (closedCurves.GetCount() < 2)
{
return true;
}
// <20><>ѡ<EFBFBD><D1A1><EFBFBD>б<EFBFBD><D0B1><EFBFBD><EFBFBD>Ƴ<EFBFBD><C6B3>պ<EFBFBD><D5BA><EFBFBD><EFBFBD>ߣ<EFBFBD><DFA3><EFBFBD>Щ<EFBFBD><D0A9><EFBFBD>߼<EFBFBD><DFBC><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD>Ƴ<EFBFBD>
CListRemoveRange(selection, closedCurves);
std::vector<CCurveEx*> left;
std::vector<CCurveEx*> right;
GroupCurves(*pXy, closedCurves, left, right);
CPositionList plAdd;
BooleanOp op = static_cast<BooleanOp>(booleanOp);
auto newCurves = PolygonCombiner::Execute(left, right, op);
for (auto& curve : newCurves)
{
POSITION pos = pXy->AddElement(curve.release(), DOUBLEFOX_CURVE);
plAdd.AddTail(pos);
}
CPositionList plDel;
CListAddRange(plDel, closedCurves);
auto pAction = std::make_unique<CActionListItem>(pView->m_pDoc, 0);
pAction->AddDeleteItem(plDel);
pAction->AddAddItem(plAdd);
pView->m_pDoc->SetActionItem(pAction.release());
pView->Notify("redraw");
return true;
}
/**
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽΪ<EFBFBD>ϲ<EFBFBD>ģʽ
*
* \param mergeIdea <EFBFBD>ϲ<EFBFBD><EFBFBD><EFBFBD>ʽ
* 0: //And
* 1: //Or
* 2: //Xor
* 3: //Cross
* \param isDelete <EFBFBD>Ƿ<EFBFBD>ɾ<EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \return <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> CItemLinkCurve <EFBFBD><EFBFBD><EFBFBD>߲<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>󣬷<EFBFBD><EFBFBD><EFBFBD> false
*/
extern "C" __declspec(dllexport)
bool SetLinkCurveMergeMode(CSigmaView * pView, int mergeIdea, bool isDelete)
{
if (pView == nullptr)
{
return false;
}
if (mergeIdea < 0 || mergeIdea > 4)
{
return false;
}
if (auto* pLinkCurve = dynamic_cast<CItemLinkCurve*>(pView->GetItem()))
{
pLinkCurve->m_nMode = LINK_CURVE_MERGE;
pLinkCurve->SetMergeIdea(mergeIdea);
pLinkCurve->SetDelete(isDelete);
}
return true;
}
/**
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ
*/
enum class LinkCurveMode
{
And,
Or,
Xor,
Cross,
};
static std::unique_ptr<CCurveEx> CCurveFromXml(const std::string& xml)
{
TiXmlDocument doc;
doc.Parse(xml.c_str());
if (doc.Error())
{
throw std::runtime_error("<EFBFBD><EFBFBD><EFBFBD>ǺϷ<EFBFBD><EFBFBD><EFBFBD> xml");
}
const char* Pline = "Pline";
const char* Point = "Point";
const char* X = "X";
const char* Y = "Y";
const char* Z = "Z";
TiXmlElement* plineElement = doc.FirstChildElement(Pline);
if (plineElement == nullptr)
{
throw std::runtime_error("xml <20><>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
}
std::vector<CPoint3D> points;
for (TiXmlElement* pointElement = plineElement->FirstChildElement(Point); pointElement != nullptr; pointElement = pointElement->NextSiblingElement(Point))
{
TiXmlElement* xElement = pointElement->FirstChildElement(X);
TiXmlElement* yElement = pointElement->FirstChildElement(Y);
TiXmlElement* zElement = pointElement->FirstChildElement(Z);
if (xElement == nullptr || yElement == nullptr || zElement == nullptr)
{
throw std::runtime_error("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD>ȱ<EFBFBD><EFBFBD> x y z <20>е<EFBFBD>Ԫ<EFBFBD><D4AA>");
}
const char* xText = xElement->GetText();
const char* yText = yElement->GetText();
const char* zText = zElement->GetText();
if (xText == nullptr || yText == nullptr || zText == nullptr)
{
throw std::runtime_error("<EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> x y z <20><><EFBFBD>е<EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
}
try
{
points.emplace_back(std::stod(xText), std::stod(yText), std::stod(zText));
}
catch (const std::invalid_argument&)
{
throw std::runtime_error("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݸ<EFBFBD>ʽ<EFBFBD><EFBFBD><EFBFBD>ǺϷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
}
}
auto pCurve = std::make_unique<CCurveEx>();
pCurve->Create(points.size());
for (size_t i = 0; i < points.size(); i++)
{
pCurve->x[i] = points[i].x0;
pCurve->y[i] = points[i].y0;
pCurve->z[i] = points[i].z0;
TRACE("%lf, %lf, %lf\n", pCurve->x[i], pCurve->y[i], pCurve->x[i]);
}
return pCurve;
}
static std::string CCurvesToXml(const std::vector<std::unique_ptr<CCurveEx>>& curves, const std::string& message)
{
TiXmlDocument doc;
std::unique_ptr<TiXmlElement> root = std::make_unique<TiXmlElement>("Polyline");
std::unique_ptr<TiXmlElement> messageElement = std::make_unique<TiXmlElement>("ErrorMessage");
messageElement->LinkEndChild(new TiXmlText(message.c_str()));
root->LinkEndChild(messageElement.release());
const char* Pline = "Pline";
const char* Point = "Point";
const char* X = "X";
const char* Y = "Y";
const char* Z = "Z";
for (const auto& curve : curves)
{
std::unique_ptr<TiXmlElement> plineElement = std::make_unique<TiXmlElement>(Pline);
for (int i = 0; i < curve->num; i++)
{
std::unique_ptr<TiXmlElement> pointElement = std::make_unique<TiXmlElement>(Point);
std::unique_ptr<TiXmlElement> xElement = std::make_unique<TiXmlElement>(X);
xElement->LinkEndChild(new TiXmlText(std::to_string(curve->x[i]).c_str()));
pointElement->LinkEndChild(xElement.release());
std::unique_ptr<TiXmlElement> yElement = std::make_unique<TiXmlElement>(Y);
yElement->LinkEndChild(new TiXmlText(std::to_string(curve->y[i]).c_str()));
pointElement->LinkEndChild(yElement.release());
std::unique_ptr<TiXmlElement> zElement = std::make_unique<TiXmlElement>(Z);
zElement->LinkEndChild(new TiXmlText(std::to_string(curve->z[i]).c_str()));
pointElement->LinkEndChild(zElement.release());
plineElement->LinkEndChild(pointElement.release());
}
root->LinkEndChild(plineElement.release());
}
doc.LinkEndChild(root.release());
TiXmlPrinter printer;
doc.Accept(&printer);
return std::string(printer.CStr());
}
static std::vector<std::unique_ptr<CCurveEx>> MergeCurveImpl(const CCurveEx& curve1, const CCurveEx& curve2, LinkCurveMode mode)
{
CCurveAnd curveAnd;
curveAnd.SetCurve(const_cast<CCurveEx*>(&curve1), const_cast<CCurveEx*>(&curve2));
switch (mode)
{
case LinkCurveMode::And:
curveAnd.GetAndCurve();
break;
case LinkCurveMode::Or:
curveAnd.GetOrCurve();
break;
case LinkCurveMode::Xor:
curveAnd.GetXorCurve();
break;
case LinkCurveMode::Cross:
curveAnd.GetCrossCurve();
break;
}
std::vector<std::unique_ptr<CCurveEx>> result;
for (POSITION pos = curveAnd.m_ptrCurveList.GetHeadPosition(); pos != nullptr; curveAnd.m_ptrCurveList.GetNext(pos))
{
CCurveEx* pCurve = reinterpret_cast<CCurveEx*>(curveAnd.m_ptrCurveList.GetAt(pos));
result.emplace_back(pCurve);
}
return result;
}
static LinkCurveMode LinkCurveModeFromString(const std::string& modeString)
{
static std::map<std::string, LinkCurveMode> map
{
{ "And", LinkCurveMode::And },
{ "Or", LinkCurveMode::Or },
{ "Xor", LinkCurveMode::Xor },
{ "Cross", LinkCurveMode::Cross },
};
if (map.find(modeString) != map.end())
{
return map.at(modeString);
}
throw std::runtime_error("error mode: " + modeString + ", only support and or xor cross");
}
static BSTR ConvertMBSToBSTR(const std::string& str)
{
int wslen = ::MultiByteToWideChar(CP_ACP, 0 /* no flags */, str.data(), str.length(), nullptr, 0);
BSTR wsdata = ::SysAllocStringLen(nullptr, wslen);
::MultiByteToWideChar(CP_ACP, 0 /* no flags */, str.data(), str.length(), wsdata, wslen);
return wsdata;
}
/**
* <EFBFBD><EFBFBD><EFBFBD>ߺϲ<EFBFBD><EFBFBD>ӿ<EFBFBD>
*
* \param curve1 <EFBFBD><EFBFBD><EFBFBD><EFBFBD>1
* \param curve2 <EFBFBD><EFBFBD><EFBFBD><EFBFBD>2
* \param mode <EFBFBD><EFBFBD><EFBFBD>ߺϲ<EFBFBD>ģʽ And Or Xor Cross
* \return
*/
extern "C" __declspec(dllexport)
BSTR MergeCurve(wchar_t* curve1, wchar_t* curve2, wchar_t* mode)
{
std::string curve1String = WStringToString(curve1);
std::string curve2String = WStringToString(curve2);
std::string modeString = WStringToString(mode);
try
{
LinkCurveMode linkMode = LinkCurveModeFromString(modeString);
std::unique_ptr<CCurveEx> curve1 = CCurveFromXml(curve1String);
std::unique_ptr<CCurveEx> curve2 = CCurveFromXml(curve2String);
std::vector<std::unique_ptr<CCurveEx>> curves = MergeCurveImpl(*curve1, *curve2, linkMode);
std::string result = CCurvesToXml(curves, "");
return ConvertMBSToBSTR(result);
}
catch (std::runtime_error& e)
{
std::string errorMessage = CCurvesToXml({}, e.what());
return ConvertMBSToBSTR(errorMessage);
}
}
static CItemCurveEditDeleteMulNodes * GetEditDeleteMulNodesFromView(CSigmaView * pView)
{
if (pView == NULL)
return 0;
CItem * pItem = pView->GetItem();
if (pItem == NULL)
return 0;
CItemCurveEditDeleteMulNodes * itemPoint = dynamic_cast<CItemCurveEditDeleteMulNodes *>(pItem);
if (itemPoint == NULL)
return 0;
return itemPoint;
}
static CItemCurveMerge * GetMergeCurveFromView(CSigmaView * pView)
{
if (pView == NULL)
return 0;
CItem * pItem = pView->GetItem();
if (pItem == NULL)
return 0;
CItemCurveMerge * itemPoint = dynamic_cast<CItemCurveMerge *>(pItem);
if (itemPoint == NULL)
return 0;
return itemPoint;
}
static CItemCurve * GetItemCurveFromView(CSigmaView * pView)
{
if (pView == NULL)
return 0;
CItem * pItem = pView->GetItem();
if (pItem == NULL)
return 0;
CItemCurve * itemPoint = dynamic_cast<CItemCurve *>(pItem);
if (itemPoint == NULL)
return 0;
return itemPoint;
}
static CItemCurveEdit * GetItemCurveEdit(CSigmaView * pView)
{
if (pView == NULL)
return NULL;
if (pView->m_pDoc == NULL)
return NULL;
CItem * pItem = pView->m_pDoc->GetItem();
if (pItem == NULL)
return NULL;
CItemSelect * pItemSelect = dynamic_cast<CItemSelect *>(pItem);
if (pItemSelect == NULL)
return NULL;
pItemSelect->InitItemForGrid();
CItem * pItemGraph = pItemSelect->GetItemForGrid();
if (pItemGraph == NULL)
return NULL;
//CItemCurveEdit* pItemCurve = dynamic_cast<CItemCurveEdit *>(pItemGraph);
CItemCurveEdit* pItemCurve = (CItemCurveEdit *)(pItemGraph);
return pItemCurve;
}
static CCurveEx * GetCurveEx(CSigmaView * pView)
{
if (pView == NULL)
return NULL;
if (pView->m_pDoc == NULL)
return NULL;
CItem * pItem = pView->m_pDoc->GetItem();
if (pItem == NULL)
return NULL;
CItemSelect * pItemSelect = dynamic_cast<CItemSelect *>(pItem);
if (pItemSelect == NULL)
return NULL;
if (pItemSelect->m_selection.IsEmpty())
return NULL;
POSITION pos = pItemSelect->m_selection.GetHead();
CXy * xy = pView->m_pDoc->m_pXy;
if (xy == NULL)
return NULL;
COne * pOne = xy->GetAt(pos);
if (pOne == NULL)
return NULL;
if (pOne->GetType() != DOUBLEFOX_CURVE)
return NULL;
//CItemCurveEdit* pItemCurve = dynamic_cast<CItemCurveEdit *>(pItemGraph);
CCurveEx * curve = (CCurveEx *)(xy->GetAtValue(pos));
return curve;
}
/*
CItemSelect * pItemSelect = dynamic_cast<CItemSelect *>(pItem);
if (pItemSelect == NULL)
return NULL;
if (pItemSelect->m_selection.GetSize() == 0)
return NULL;
POSITION pos = pItemSelect->m_selection.GetHead();
CXy * xy = pView->m_pDoc->m_pXy;
if (xy == 0)
return NULL;
COne * pOne = xy->GetAt(pos);
pOne->GetType();
*/
static bool getNodeFromCurve(CCurveEx* pcIn, CurveNode * nodeOut, int nodeIndex)
{
if (pcIn == NULL || nodeOut == NULL)
return false;
if (nodeIndex < 0 || nodeIndex >= pcIn->num)
return false;
nodeOut->x = pcIn->x[nodeIndex];
nodeOut->y = pcIn->y[nodeIndex];
nodeOut->z = pcIn->z[nodeIndex];
nodeOut->len = pcIn->l[nodeIndex];
if (nodeIndex == 0)
nodeOut->realLen = 0;
else
nodeOut->realLen = AfxGetPublicFunction()->Distance(pcIn->x[nodeIndex - 1], pcIn->y[nodeIndex - 1], pcIn->x[nodeIndex], pcIn->y[nodeIndex]);
if (nodeIndex == 0)
nodeOut->angle = 0;
else
nodeOut->angle = ::_GetAngle(pcIn->x[nodeIndex - 1], pcIn->y[nodeIndex - 1], pcIn->x[nodeIndex], pcIn->y[nodeIndex]);
return true;
}
static double _GetAngle(double x1, double y1, double x2, double y2)
{
double dx = x2 - x1;
double dy = y2 - y1;
return atan2(dy, dx)*RHO;
1 month ago
}
static std::vector<CCurveEx*> ConverToVector(CXy* pXy, CPositionList& positions)
{
std::vector<CCurveEx*> result;
result.reserve(positions.GetCount());
for (POSITION pos = positions.GetHeadPosition(); pos != nullptr; positions.GetNext(pos))
{
POSITION pt = positions.GetAt(pos);
COne* pOne = pXy->GetAt(pt);
if (pOne->GetType() == DOUBLEFOX_CURVE)
{
result.push_back(pOne->GetValueSafe<CCurveEx>());
}
}
return result;
}
static std::optional<CPoint2D> GetBoundsCenter(const CCurveEx* pCurve)
{
if (pCurve == nullptr || pCurve->num < 2)
{
return std::nullopt;
}
auto xRange = std::minmax_element(pCurve->x, pCurve->x + pCurve->num);
auto yRange = std::minmax_element(pCurve->y, pCurve->y + pCurve->num);
double centerX = (*xRange.first + *xRange.second) / 2.0;
double centerY = (*yRange.first + *yRange.second) / 2.0;
return CPoint2D { centerX, centerY };
}
static POSITION AddTextMarker(CXy* pXy, CLayer* pLayer, double centerX, double centerY, const char* text)
{
// <20><><EFBFBD><EFBFBD>ԭ<EFBFBD><D4AD><EFBFBD>߼<EFBFBD><DFBC>еijߴ<C4B3><DFB4><EFBFBD><EFBFBD><EFBFBD>
double width = 10.0;
double height = 26.0;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͻ<EFBFBD>λ<EFBFBD><CEBB><><D4AD><EFBFBD>߼<EFBFBD>)
double textX = centerX - (width / 2.0);
double textY = centerY + (height / 2.0);
std::unique_ptr<CText> pText = CTextBuilder()
.FontLocation(textX, textY)
.FontSize(width, height)
.Text(text)
.Build();
COne* pOne = new COne();
pOne->SetValueSafe(pText.release());
pOne->SetLayer(pLayer);
return pXy->AddTailOne(pOne);
}
/**
* <EFBFBD>պ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* \param pView
* \param layers
*/
static std::unique_ptr<CActionBackupItem> CloseCurve(CSigmaView* pView, const std::vector<CString>& layers)
{
CXy* pXy = pView->m_pDoc->m_pXy;
CXyElementFilter filter;
for (const auto& layer : layers)
{
filter.addLayer(layer, false);
}
filter.addType(DOUBLEFOX_CURVE);
CPositionList select;
pXy->GetElement(filter, select);
std::unique_ptr<CActionBackupItem> pItem = std::make_unique<CActionBackupItem>(pView->m_pDoc, 0);
for (POSITION pos = select.GetHeadPosition(); pos != nullptr; select.GetNext(pos))
{
POSITION pt = select.GetAt(pos);
COne* pOne = pXy->GetAt(pt);
CCurveEx* pCurve = pOne->GetValueSafe<CCurveEx>();
if (!pCurve->IsClosed())
{
pItem->Backup(pOne);
std::unique_ptr<CCurveEx> pClosedCurve(CreateCloseCurve(pCurve));
*pCurve = *pClosedCurve;
}
}
pItem->BackupNew();
return pItem;
}
static std::unique_ptr<CActionBackupItem> ResolveSnap(CSigmaView* pView, const std::vector<CString>& layers, double gap, double degrees, double snapRadius, double maxExtension)
{
CXy* pXy = pView->m_pDoc->m_pXy;
CXyElementFilter filter;
filter.addType(DOUBLEFOX_CURVE);
for (const auto& layer : layers)
{
filter.addLayer(layer, false);
}
CPositionList select;
pXy->GetElement(filter, select);
double delta = gap;
std::vector<CCurveEx*> curves;
curves.reserve(select.GetCount());
std::unique_ptr<CActionBackupItem> pItem = std::make_unique<CActionBackupItem>(pView->m_pDoc, 0);
for (POSITION pos = select.GetHeadPosition(); pos != nullptr; select.GetNext(pos))
{
POSITION pt = select.GetAt(pos);
COne* pOne = pXy->GetAt(pt);
pItem->Backup(pOne);
CCurveEx* pCurve = pOne->GetValueSafe<CCurveEx>();
curves.push_back(pCurve);
}
PolygonSnapper::Snap(curves, gap, degrees, snapRadius, maxExtension);
pItem->BackupNew();
return pItem;
}