#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(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; } //获得选中曲线的坐标数量 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; //保存文件头 if (fputs("X, Y, Z, L, 实际长度, 角度\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) //返回添加的节点的索引 出错返回-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) //返回添加的节点的索引 出错返回-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出错 1 默认光标 2 添加光标 3 移动光标 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))//当移动到曲线上时设置为增加点光标 { 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(); } // 区域连通 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); } //加密曲线节点 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中 将item的类型设置为ITEM_SELECT 在调用此函数时 还未切换Item 所以当前的Item还是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; } //去掉曲线上冗余的节点 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中 将item的类型设置为ITEM_SELECT 在调用此函数时 还未切换Item 所以当前的Item还是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; } /// 自动连接曲线 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中 将item的类型设置为ITEM_SELECT 在调用此函数时 当前的Item还是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; } /** * 获取角度和距离 * * \param pView * \return 如果失败,返回空字符串,否则返回由 "," 分割的字符串,第一个是角度,第二个距离 */ 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(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(); if (pCurve->IsClosed()) { closedCurves.AddTail(pt); } } } } static void GroupCurves(CXy& xy, CPositionList& curves, std::vector& left, std::vector& 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(); if (left.size() < half) { left.push_back(pCurve); } else { right.push_back(pCurve); } } } /** * 多边形运算 * * \param pView pView * \param booleanOp 合并方式 * 0: // Difference * 1: // Intersect * 2: // Union * 3: // XOR * \return */ extern "C" __declspec(dllexport) bool PolygonBooleanOperation(CSigmaView* pView, int booleanOp) { if (pView == nullptr) { TRACE("pView 不能为 nullptr\n"); return false; } if (booleanOp < 0 || booleanOp > 3) { TRACE("booleanOp 必须在 [0, 3] 之间\n"); return false; } auto* pItem = pView->GetItem(); if (pItem == nullptr) { return false; } CItemSelect * pItemSelect = dynamic_cast(pItem); if (pItemSelect == nullptr) { TRACE("必须先选中曲线\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; } // 从选中列表中移除闭合曲线,这些曲线即将从图件中移除 CListRemoveRange(selection, closedCurves); std::vector left; std::vector right; GroupCurves(*pXy, closedCurves, left, right); CPositionList plAdd; BooleanOp op = static_cast(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(pView->m_pDoc, 0); pAction->AddDeleteItem(plDel); pAction->AddAddItem(plAdd); pView->m_pDoc->SetActionItem(pAction.release()); pView->Notify("redraw"); return true; } /** * 设置连接模式为合并模式 * * \param mergeIdea 合并方式 * 0: //And * 1: //Or * 2: //Xor * 3: //Cross * \param isDelete 是否删除原来的线 * \return 如果当前不是 CItemLinkCurve 或者参数错误,返回 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(pView->GetItem())) { pLinkCurve->m_nMode = LINK_CURVE_MERGE; pLinkCurve->SetMergeIdea(mergeIdea); pLinkCurve->SetDelete(isDelete); } return true; } /** * 曲线连接模式 */ enum class LinkCurveMode { And, Or, Xor, Cross, }; static std::unique_ptr CCurveFromXml(const std::string& xml) { TiXmlDocument doc; doc.Parse(xml.c_str()); if (doc.Error()) { throw std::runtime_error("不是合法的 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 中没有数据"); } std::vector 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("点数据元素缺少 x y z 中的元素"); } 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("点元素中 x y z 中有的没有内容"); } try { points.emplace_back(std::stod(xText), std::stod(yText), std::stod(zText)); } catch (const std::invalid_argument&) { throw std::runtime_error("点数据格式不是合法的数字"); } } auto pCurve = std::make_unique(); 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>& curves, const std::string& message) { TiXmlDocument doc; std::unique_ptr root = std::make_unique("Polyline"); std::unique_ptr messageElement = std::make_unique("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 plineElement = std::make_unique(Pline); for (int i = 0; i < curve->num; i++) { std::unique_ptr pointElement = std::make_unique(Point); std::unique_ptr xElement = std::make_unique(X); xElement->LinkEndChild(new TiXmlText(std::to_string(curve->x[i]).c_str())); pointElement->LinkEndChild(xElement.release()); std::unique_ptr yElement = std::make_unique(Y); yElement->LinkEndChild(new TiXmlText(std::to_string(curve->y[i]).c_str())); pointElement->LinkEndChild(yElement.release()); std::unique_ptr zElement = std::make_unique(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> MergeCurveImpl(const CCurveEx& curve1, const CCurveEx& curve2, LinkCurveMode mode) { CCurveAnd curveAnd; curveAnd.SetCurve(const_cast(&curve1), const_cast(&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> result; for (POSITION pos = curveAnd.m_ptrCurveList.GetHeadPosition(); pos != nullptr; curveAnd.m_ptrCurveList.GetNext(pos)) { CCurveEx* pCurve = reinterpret_cast(curveAnd.m_ptrCurveList.GetAt(pos)); result.emplace_back(pCurve); } return result; } static LinkCurveMode LinkCurveModeFromString(const std::string& modeString) { static std::map 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; } /** * 曲线合并接口 * * \param curve1 曲线1 * \param curve2 曲线2 * \param mode 曲线合并模式 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 curve1 = CCurveFromXml(curve1String); std::unique_ptr curve2 = CCurveFromXml(curve2String); std::vector> 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(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(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(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(pItem); if (pItemSelect == NULL) return NULL; pItemSelect->InitItemForGrid(); CItem * pItemGraph = pItemSelect->GetItemForGrid(); if (pItemGraph == NULL) return NULL; //CItemCurveEdit* pItemCurve = dynamic_cast(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(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(pItemGraph); CCurveEx * curve = (CCurveEx *)(xy->GetAtValue(pos)); return curve; } /* CItemSelect * pItemSelect = dynamic_cast(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; }