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.
kev/Drawer/Module/GeoSigmaDraw/InterfaceCurve.cpp

1087 lines
25 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "Stdafx.h"
#include "SigmaView.h"
#include "ItemCurveArc.h"
#include "ItemCurveEdit.h"
#include "ItemSelect.h"
#include "ItemCurveProcess.h"
#include "ItemCurveEditDeleteMulNodes.h"
#include "ActionListItem.h"
#include "BufferAgency.h"
#include "ItemLinkCurve.h"
#include "TinyXml/tinyxml.h"
#include "PolygonCombiner.h"
#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);
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);
}
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;
}
/**
* <20><>ȡ<EFBFBD>ǶȺ;<C8BA><CDBE><EFBFBD>
*
* \param pView
* \return <20><><EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD>ؿ<EFBFBD><D8BF>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>򷵻<EFBFBD><F2B7B5BB><EFBFBD> "," <20>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ǽǶȣ<C7B6><C8A3>ڶ<EFBFBD><DAB6><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;
}
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);
}
}
}
/**
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* \param pView pView
* \param booleanOp <09>ϲ<EFBFBD><CFB2><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;
}
/**
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽΪ<CABD>ϲ<EFBFBD>ģʽ
*
* \param mergeIdea <20>ϲ<EFBFBD><CFB2><EFBFBD>ʽ
* 0: //And
* 1: //Or
* 2: //Xor
* 3: //Cross
* \param isDelete <20>Ƿ<EFBFBD>ɾ<EFBFBD><C9BE>ԭ<EFBFBD><D4AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD> CItemLinkCurve <20><><EFBFBD>߲<EFBFBD><DFB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>󣬷<EFBFBD><F3A3ACB7><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;
}
/**
* <20><><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;
}
/**
* <20><><EFBFBD>ߺϲ<DFBA><CFB2>ӿ<EFBFBD>
*
* \param curve1 <20><><EFBFBD><EFBFBD>1
* \param curve2 <20><><EFBFBD><EFBFBD>2
* \param mode <20><><EFBFBD>ߺϲ<DFBA>ģʽ 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;
}