#include "EditGeomInterpreter.h" #include "CurveInterpreter.h" #include "Constants.h" #include "DataManager.h" #include #include #include // For mathematical operations like std::abs and std::sqrt #include // For std::numeric_limits #include #include "DataManagerGlobal.h" #include "Common/tangible_string_helper.h" #include "Interfaces.h" #include "CommandStreamProcessing.h" CopyInterpreter::CopyInterpreter() { } void CopyInterpreter::ExecuteCommand(std::vector &commandLines, IModel *&o) { // XUEFENG ADDED 202201 bool OnlyOneName = false; // END ADDED // 名称行 std::string cmdTmp = ""; std::vector lineName = StringHelper::GetWords(commandLines[0]); commandLines.erase(commandLines.begin()); if (commandLines.empty()) { throw std::runtime_error("缺少参数!"); } // 解析 SOURCE 行 std::vector paraline = StringHelper::GetWords(commandLines[0]); if (StringHelper::toUpper(paraline[0]) != "SOURCE" || paraline.size() < 2) { throw std::runtime_error("缺少关键字 SOURCE 或未指定源!"); } commandLines.erase(commandLines.begin()); if (commandLines.empty()) { throw std::runtime_error("缺少参数!"); } // 解析 OFFSET 行 std::string offset = commandLines[0]; std::vector offsetline = StringHelper::GetWords(commandLines[0]); if (StringHelper::toUpper(offsetline[0]) != "OFFSET" || offsetline.size() != 2) { throw std::runtime_error("缺少关键字 OFFSET 或偏移量格式不正确!"); } std::vector s = StringHelper::split( StringHelper::replace( StringHelper::replace(offsetline[1], "(", ""), ")", ""), std::vector{WORD_SPLITTER_2,WORD_SPLITTER}); if (s.size() != 3) { throw std::runtime_error("偏移量参数错误!"); } double dx = std::stod(s[0]); double dy = std::stod(s[1]); double dz = std::stod(s[2]); commandLines.erase(commandLines.begin()); // 检查名称和源的数量是否匹配 if (lineName.size() > 2 && lineName.size() != paraline.size()) { throw std::runtime_error("缺少关键字OFFSET,或未指定偏移量,或偏移量格式不正确“(dx, dy ,dz)”"); } // 检查源是否有重复 for (size_t cnt = 1; cnt < paraline.size(); cnt++) { for (size_t cnt1 = cnt + 1; cnt1 < paraline.size(); cnt1++) { if (paraline[cnt] == paraline[cnt1]) { throw std::runtime_error("复制的图元序列有重复:" + paraline[cnt]); } } } // 遍历每个源对象进行复制 for (size_t i = 1; i < paraline.size(); i++) { int id = DataManager::GetObjectIDByName(paraline[i]); if (id == -1) { throw std::runtime_error("未找到对象:" + paraline[i]); } IModel *src = DataManager::GetObjectByID(id); // 确定名称 std::string nameStr = ""; std::string name = ""; if (lineName.size() == 1) // 未指定名称 { nameStr = lineName[0]; if (!ParseName(*src, name, nameStr)) { throw std::runtime_error("命名重复!"); } } else if (lineName.size() == 2) // 仅指定了一个名称 { // XUEFENG ADDED 202201 OnlyOneName = true; // END ADDED if (typeid(src) == typeid(Hull)) { if (i > 1) { name = ParseNameHull(); } else { name = ParseNameByPre(lineName[1]); std::regex reg_hull(Reg_HULL); if (!std::regex_match(StringHelper::toUpper(name), reg_hull)) { throw std::runtime_error("主船体命名格式不正确!"); } } } else { name = ParseNameByPre(lineName[1]); } nameStr = lineName[0] + " " + name; } else // 指定了对应名称 { nameStr = lineName[0] + " " + lineName[i]; if (!ParseName(*src, name, nameStr)) { throw std::runtime_error("命名重复!"); } } // XUEFENG ADDED 202201 if (OnlyOneName) { name += "_" + paraline[i]; } // END ADDED nameStr = lineName[0] + " " + name; // 复制对象数据 // IModel *o = nullptr; bool bNormalCopy = true; // 是否正常复制 if (typeid(*src).name() == typeid(Point3D_M).name()) { bNormalCopy = false; o = new Point3D_M(CopyPoint(*static_cast(src), name, dx, dy, dz)); o->m_Type = 0; } else if (typeid(*src).name() == typeid(Curve_M).name()) { bNormalCopy = false; o = new Curve_M(CopyCurve(*static_cast(src), name, dx, dy, dz)); o->m_Type = 14; } else if (typeid(*src).name() == typeid(Surface_M).name()) { bNormalCopy = true; Surface_M *surf = new Surface_M(*static_cast(src)); surf->m_CopyOffsetX = dx; surf->m_CopyOffsetY = dy; surf->m_CopyOffsetZ = dz; surf->m_Src.clear(); surf->m_Src.resize(ModelData::ARRAY_SIZE_NORMAL); surf->m_Src[0] = src->m_ID; o = surf; // 最后再赋给 IModel* 类型 o->m_Name = QString::fromStdString(name); o->m_Type = 14; } else if (typeid(*src).name() == typeid(Solid_M).name()) { bNormalCopy = true; Solid_M *oo = new Solid_M(*static_cast(src)); // static_cast(src); oo->m_CopyOffsetX = dx; oo->m_CopyOffsetY = dy; oo->m_CopyOffsetZ = dz; oo->m_Src.clear(); oo->m_Src.resize(ModelData::ARRAY_SIZE_NORMAL); oo->m_Src[0] = src->m_ID; o = oo; o->m_Name = QString::fromStdString(name); o->m_Type = 14; } else if (typeid(*src).name() == typeid(Hull_M).name()) { bNormalCopy = true; Hull_M *oo = new Hull_M(*static_cast(src)); // static_cast(src); oo->m_CopyOffsetX = dx; oo->m_CopyOffsetY = dy; oo->m_CopyOffsetZ = dz; oo->m_Src.clear(); oo->m_Src.resize(ModelData::ARRAY_SIZE_NORMAL); oo->m_Src[0] = src->m_ID; o = oo; o->m_Name = QString::fromStdString(name); o->m_Type = 14; } else if (typeid(*src).name() == typeid(Space_M).name()) { bNormalCopy = true; Space_M *oo = new Space_M(*static_cast(src)); // static_cast(src); oo->m_CopyOffsetX = dx; oo->m_CopyOffsetY = dy; oo->m_CopyOffsetZ = dz; oo->m_Src.clear(); oo->m_Src.resize(ModelData::ARRAY_SIZE_NORMAL); oo->m_Src[0] = src->m_ID; o = oo; o->m_Name = QString::fromStdString(name); o->m_Type = 14; } else if (typeid(*src).name() == typeid(Appendage_M).name()) { bNormalCopy = true; Appendage_M *oo = new Appendage_M(*static_cast(src)); // static_cast(src); oo->m_CopyOffsetX = dx; oo->m_CopyOffsetY = dy; oo->m_CopyOffsetZ = dz; oo->m_Src.clear(); oo->m_Src.resize(ModelData::ARRAY_SIZE_NORMAL); oo->m_Src[0] = src->m_ID; o = oo; o->m_Name = QString::fromStdString(name); o->m_Type = 14; } // 构建命令 std::string cmd; cmd += LINE_SPLITTER + nameStr; cmd += LINE_SPLITTER + paraline[0] + " " + paraline[i]; cmd += LINE_SPLITTER + offset; Add2ModelOrInteractWithIdtf(o, bNormalCopy); // 不更改 o.Command cmdTmp += cmd; o->m_Command = QString::fromStdString(cmdTmp); } } Point3D_M CopyInterpreter::CopyPoint(const Point3D_M &srcPoint, const std::string &newName, double dx, double dy, double dz) { // 拷贝数据 Point3D_M o = srcPoint; o.m_Name = QString::fromStdString(newName); // 解析命令行并重构 try { // 分割命令行 std::vector commandLines = StringHelper::split(srcPoint.m_Command.toStdString(), std::vector{LINE_SPLITTER}); std::vector newCommandLines; // 处理第一行命令 if (commandLines.empty()) { throw std::runtime_error("原图元命令行为空,无法复制!"); } std::string newCmdLine = "POINT " + o.m_Name.toStdString(); newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); // 处理参数行 if (commandLines.empty()) { throw std::runtime_error("缺少参数行!"); } std::vector lineLoc = StringHelper::GetWords(commandLines[0]); if (lineLoc.size() < 2 || StringHelper::toUpper(lineLoc[0]) != "LOC") { throw std::runtime_error("参数行格式错误或缺少 LOC 关键字!"); } // 解析坐标并应用偏移 Point3D_M tp; if (!ParsePointLoc(tp, lineLoc[1])) { throw std::runtime_error("参数行坐标解析失败!"); } tp.m_X += dx; tp.m_Y += dy; tp.m_Z += dz; // 更新对象的坐标 o.m_X = tp.m_X; o.m_Y = tp.m_Y; o.m_Z = tp.m_Z; // 构建新的 LOC 行 newCmdLine = "LOC (" + std::to_string(tp.m_X) + "," + std::to_string(tp.m_Y) + "," + std::to_string(tp.m_Z) + ")"; newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); // 重新构建命令行 std::string newCommand; for (const auto &line : newCommandLines) { newCommand += line + LINE_SPLITTER; } o.m_Command = QString::fromStdString(newCommand); } catch (const std::exception &e) { throw std::runtime_error("原图元命令行有误,无法复制:" + std::string(e.what())); } return o; } Curve_M CopyInterpreter::CopyCurve(const Curve_M &srcCurve, const std::string &newName, double dx, double dy, double dz) { // 拷贝数据 Curve_M o = srcCurve; // 假设 Curve_M 支持直接拷贝构造 o.m_Name = QString::fromStdString(newName); o.m_CopyOffsetX = dx; o.m_CopyOffsetY = dy; o.m_CopyOffsetZ = dz; o.m_Src.resize(ModelData::ARRAY_SIZE_NORMAL); o.m_Src[0] = srcCurve.m_ID; // 拷贝节点 std::vector pList; // 节点坐标 if (!srcCurve.m_KnotID.empty()) { o.m_KnotID.resize(ModelData::ARRAY_SIZE_NORMAL); for (size_t i = 0; i < srcCurve.m_KnotID.size(); i++) { int cid = srcCurve.m_KnotID[i]; if (cid == 0) break; Point3D_M *tp = static_cast(DataManager::GetObjectByID(cid)); tp->m_X += dx; tp->m_Y += dy; tp->m_Z += dz; tp->m_ID = GenerateObjectID(tp); tp->m_Type = 0; o.m_KnotID[i] = tp->m_ID; o.m_Src[i + 1] = tp->m_ID; pList.push_back(*tp); } } // 解析命令行并重构 try { std::vector commandLines = StringHelper::split(srcCurve.m_Command.toStdString(), std::vector{LINE_SPLITTER}); std::vector newCommandLines; CurveInterpreter tmpCurve_Interpreter; if (commandLines.empty()) { throw std::runtime_error("原曲线命令行为空,无法复制!"); } // 主命令行 std::string newCmdLine = StringHelper::FirstWord(commandLines[0]); if (StringHelper::toUpper(newCmdLine) == "CURVE") { o.m_Type = 0; } else if (StringHelper::toUpper(newCmdLine) == "ELLIPSE") { o.m_Type = 2; } else if (StringHelper::toUpper(newCmdLine) == "PARABOLA") { o.m_Type = 3; } else { throw std::runtime_error("不支持的曲线类型!"); } newCmdLine += " " + o.m_Name.toStdString(); newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); o.m_Full = false; // 根据曲线类型解析参数行 switch (o.m_Type) { case 0: { // 普通曲线 std::vector linePara = StringHelper::GetWords(commandLines[0]); if (StringHelper::toUpper(linePara[0]) == "XYZ") { newCmdLine = StringHelper::toUpper(linePara[0]); o.m_Type = 5; // 节点索引 for (size_t i = 1; i < linePara.size(); i++) { if (linePara[i] == "/-") { // 折点切出 tmpCurve_Interpreter.SetKnotAXYZII(o, i - 1, 0, 0, 0); o.m_KnotDirII[i - 1] = 2; newCmdLine += " " + linePara[i]; } else if (linePara[i] == "-/") { // 折点切入 tmpCurve_Interpreter.SetKnotAXYZ(o, i, 0, 0, 0); o.m_KnotDir[i] = 2; newCmdLine += " " + linePara[i]; } else { // 坐标点 Point3D_M tp = pList[i - 1]; newCmdLine += " (" + std::to_string(tp.m_X) + "," + std::to_string(tp.m_Y) + "," + std::to_string(tp.m_Z) + ")"; } } newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); } else if (StringHelper::toUpper(linePara[0]) == "X" || StringHelper::toUpper(linePara[0]) == "Y" || StringHelper::toUpper(linePara[0]) == "Z") { std::string dir1 = StringHelper::toUpper(linePara[0]); Point3D_M tp; // 平面位置行 o.m_Type = 5; double offset = 10000; // 位置面的坐标分量 ParseLoc(linePara, dir1, offset); if (dir1 == "X") { o.m_ProjIDir = 0; offset += dx; } else if (dir1 == "Y") { o.m_ProjIDir = 1; offset += dy; } else if (dir1 == "Z") { o.m_ProjIDir = 2; offset += dz; } else { throw std::runtime_error("参数错误!"); } newCmdLine = dir1 + " " + std::to_string(offset); newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); // 平面坐标序列行 linePara = StringHelper::GetWords(commandLines[0]); newCmdLine = StringHelper::toUpper(linePara[0]); size_t m = 0; // 节点索引 for (size_t i = 1; i < linePara.size(); i++) { if (linePara[i] == "/-") { // 折点切出 tmpCurve_Interpreter.SetKnotAXYZII(o, m - 1, 0, 0, 0); o.m_KnotDirII[m - 1] = 2; newCmdLine += " " + linePara[i]; } else if (linePara[i] == "-/") { // 折点切入 tmpCurve_Interpreter.SetKnotAXYZ(o, m, 0, 0, 0); o.m_KnotDir[m] = 2; newCmdLine += " " + linePara[i]; } else { // 节点表达式 tp = pList[m]; if (dir1 == "X") { newCmdLine += " (" + std::to_string(tp.m_Y) + "," + std::to_string(tp.m_Z) + ")"; } else if (dir1 == "Y") { newCmdLine += " (" + std::to_string(tp.m_X) + "," + std::to_string(tp.m_Z) + ")"; } else if (dir1 == "Z") { newCmdLine += " (" + std::to_string(tp.m_X) + "," + std::to_string(tp.m_Y) + ")"; } m++; } } o.m_ProjIKnotCnt = m; newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); } else { throw std::runtime_error("参数行格式错误!"); } break; } case 2: // 椭圆 { // 椭圆处理 std::string dir_Ellipse = ""; double loc_Ellipse = 10000; if (commandLines.empty()) { throw std::runtime_error("缺少参数!"); } // 解析位置面行 std::vector linePara1e = StringHelper::GetWords(commandLines[0]); dir_Ellipse = StringHelper::toUpper(linePara1e[0]); if (dir_Ellipse == "X" || dir_Ellipse == "Y" || dir_Ellipse == "Z") { if (linePara1e.size() != 2) { throw std::runtime_error("参数错误!"); } ParseLoc(linePara1e, linePara1e[0], loc_Ellipse); if (dir_Ellipse == "X") { loc_Ellipse += dx; } else if (dir_Ellipse == "Y") { loc_Ellipse += dy; } else if (dir_Ellipse == "Z") { loc_Ellipse += dz; } newCmdLine = dir_Ellipse + " " + std::to_string(loc_Ellipse); newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); } else if (dir_Ellipse == "DP") { // 梁拱处理 } else { throw std::runtime_error("参数错误!"); } if (commandLines.empty()) { throw std::runtime_error("缺少参数!"); } // 解析中心坐标行 linePara1e = StringHelper::GetWords(commandLines[0]); if (StringHelper::toUpper(linePara1e[0]) == "CENTER") { Point3D_M tp; o.m_Type = 2; if (linePara1e.size() != 2) { throw std::runtime_error("参数错误!"); } ParsePointLoc2D(tp, linePara1e[1], dir_Ellipse, loc_Ellipse); tp.m_X += dx; tp.m_Y += dy; tp.m_Z += dz; o.m_OX = tp.m_X; o.m_OY = tp.m_Y; o.m_OZ = tp.m_Z; o.m_VX = tp.m_X; o.m_VY = tp.m_Y; o.m_VZ = tp.m_Z; if (dir_Ellipse == "X") { o.m_VX += 1; newCmdLine = "CENTER (" + std::to_string(tp.m_Y) + "," + std::to_string(tp.m_Z) + ")"; } else if (dir_Ellipse == "Y") { o.m_VY += 1; newCmdLine = "CENTER (" + std::to_string(tp.m_X) + "," + std::to_string(tp.m_Z) + ")"; } else if (dir_Ellipse == "Z") { o.m_VZ += 1; newCmdLine = "CENTER (" + std::to_string(tp.m_X) + "," + std::to_string(tp.m_Y) + ")"; } newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); // 解析半径行 if (commandLines.empty()) { throw std::runtime_error("缺少参数!"); } std::vector linePara1b = StringHelper::GetWords(commandLines[0]); if (StringHelper::toUpper(linePara1b[0]) != "R" || linePara1b.size() < 2 || linePara1b.size() > 3) { throw std::runtime_error("参数错误!"); } o.m_R1 = std::stod(linePara1b[1]); if (linePara1b.size() == 3) { o.m_R2 = std::stod(linePara1b[2]); if (o.m_R2 < 0) { throw std::runtime_error("椭圆弧半径(R2)应为正实数"); } } else { o.m_R2 = o.m_R1; } if (o.m_R1 <= 0 || o.m_R2 <= 0) { throw std::runtime_error("椭圆弧半径应大于 0!"); } newCmdLine = commandLines[0]; newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); // 解析角度行 o.m_A1 = 0; o.m_A2 = 360; if (!commandLines.empty()) { std::vector lineParaagl = StringHelper::GetWords(commandLines[0]); if (StringHelper::toUpper(lineParaagl[0]) != "ANGLE") { throw std::runtime_error("参数错误!"); } if (lineParaagl.size() != 3) { throw std::runtime_error("参数错误!"); } o.m_A1 = std::stod(lineParaagl[1]); o.m_A2 = std::stod(lineParaagl[2]); if (o.m_A1 < -360 || o.m_A1 > 360 || o.m_A2 < -360 || o.m_A2 > 360) { throw std::runtime_error("椭圆弧角度值范围应为 [-360, 360]!"); } else if (o.m_A1 >= o.m_A2) { throw std::runtime_error("椭圆弧起始角度应小于终止角度!"); } newCmdLine = commandLines[0]; newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); } } else if (StringHelper::toUpper(linePara1e[0]) == "LOC") { // 三点处理 o.m_Type = 7; if (linePara1e.size() != 4) { throw std::runtime_error("参数错误!"); } Point3D_M tp2d1 = pList[0]; o.m_P1X = tp2d1.m_X; o.m_P1Y = tp2d1.m_Y; o.m_P1Z = tp2d1.m_Z; Point3D_M tp2d2 = pList[1]; o.m_OX = tp2d2.m_X; o.m_OY = tp2d2.m_Y; o.m_OZ = tp2d2.m_Z; Point3D_M tp2d3 = pList[2]; o.m_P2X = tp2d3.m_X; o.m_P2Y = tp2d3.m_Y; o.m_P2Z = tp2d3.m_Z; newCmdLine = "LOC"; if (dir_Ellipse == "X") { for (int k = 0; k < 3; k++) { Point3D_M tp = pList[k]; newCmdLine += " (" + std::to_string(tp.m_Y) + "," + std::to_string(tp.m_Z) + ")"; } } else if (dir_Ellipse == "Y") { for (int k = 0; k < 3; k++) { Point3D_M tp = pList[k]; newCmdLine += " (" + std::to_string(tp.m_X) + "," + std::to_string(tp.m_Z) + ")"; } } else if (dir_Ellipse == "Z") { for (int k = 0; k < 3; k++) { Point3D_M tp = pList[k]; newCmdLine += " (" + std::to_string(tp.m_X) + "," + std::to_string(tp.m_Y) + ")"; } } newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); } else if (dir_Ellipse == "DP") { // 梁拱处理 o.m_Type = 2; if (linePara1e.size() != 2) { throw std::runtime_error("参数错误!"); } Point3D_M tp2d; ParsePointLoc(tp2d, linePara1e[1], true); tp2d.m_X += dx; tp2d.m_Y += dy; tp2d.m_Z += dz; newCmdLine = "DP (" + std::to_string(tp2d.m_X) + "," + std::to_string(tp2d.m_Y) + "," + std::to_string(tp2d.m_Z) + ")"; newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); // 梁拱宽度、高度和中心点行 if (commandLines.empty()) { throw std::runtime_error("缺少参数!"); } std::vector linePararw = StringHelper::GetWords(commandLines[0]); if (StringHelper::toUpper(linePararw[0]) != "BFY" || linePararw.size() < 3 || linePararw.size() > 4) { throw std::runtime_error("参数错误!"); } double B = std::stod(linePararw[1]); double f = std::stod(linePararw[2]); double Yc = (linePararw.size() == 4) ? std::stod(linePararw[3]) : 0.0; Yc += dy; if (B == 0 || std::abs(B) < 2 * std::abs(f)) { throw std::runtime_error("梁拱宽度 B 不能为 0,也不能小于梁拱高度 f 的 2 倍!"); } newCmdLine = "BfY " + std::to_string(B) + " " + std::to_string(f) + " " + std::to_string(Yc); newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); // 是否全甲板行 if (!commandLines.empty()) { std::vector str = StringHelper::GetWords(commandLines[0]); if (StringHelper::toUpper(str[0]) == "FULL") { o.m_Full = true; newCmdLine = commandLines[0]; newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); } } // 重新计算圆心位置 o.m_OX += dx; o.m_OY += dy; o.m_OZ += dz; } else { throw std::runtime_error("参数错误!"); } break; } case 3: // 抛物线 { // 解析位置面行 std::vector linePara1e = StringHelper::GetWords(commandLines[0]); std::string dir_Ellipse = StringHelper::toUpper(linePara1e[0]); double loc_Ellipse = 0; if (dir_Ellipse == "X" || dir_Ellipse == "Y" || dir_Ellipse == "Z") { if (linePara1e.size() != 2) { throw std::runtime_error("参数错误!"); } ParseLoc(linePara1e, linePara1e[0], loc_Ellipse); if (dir_Ellipse == "X") { loc_Ellipse += dx; } else if (dir_Ellipse == "Y") { loc_Ellipse += dy; } else if (dir_Ellipse == "Z") { loc_Ellipse += dz; } newCmdLine = dir_Ellipse + " " + std::to_string(loc_Ellipse); newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); } else if (dir_Ellipse == "DP") { // 梁拱处理 } else { throw std::runtime_error("参数错误!"); } if (commandLines.empty()) { throw std::runtime_error("缺少参数!"); } // 解析 LOC 或 DP 行 linePara1e = StringHelper::GetWords(commandLines[0]); if (StringHelper::toUpper(linePara1e[0]) == "LOC") { // 三点抛物线处理 if (linePara1e.size() != 4) { throw std::runtime_error("参数错误!"); } Point3D_M tp2d1 = pList[0]; o.m_P1X = tp2d1.m_X; o.m_P1Y = tp2d1.m_Y; o.m_P1Z = tp2d1.m_Z; Point3D_M tp2d2 = pList[1]; o.m_OX = tp2d2.m_X; o.m_OY = tp2d2.m_Y; o.m_OZ = tp2d2.m_Z; Point3D_M tp2d3 = pList[2]; o.m_P2X = tp2d3.m_X; o.m_P2Y = tp2d3.m_Y; o.m_P2Z = tp2d3.m_Z; newCmdLine = "LOC"; if (dir_Ellipse == "X") { for (int k = 0; k < 3; k++) { Point3D_M tp = pList[k]; newCmdLine += " (" + std::to_string(tp.m_Y) + "," + std::to_string(tp.m_Z) + ")"; } } else if (dir_Ellipse == "Y") { for (int k = 0; k < 3; k++) { Point3D_M tp = pList[k]; newCmdLine += " (" + std::to_string(tp.m_X) + "," + std::to_string(tp.m_Z) + ")"; } } else if (dir_Ellipse == "Z") { for (int k = 0; k < 3; k++) { Point3D_M tp = pList[k]; newCmdLine += " (" + std::to_string(tp.m_X) + "," + std::to_string(tp.m_Y) + ")"; } } newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); } else if (StringHelper::toUpper(linePara1e[0]) == "DP") { // 抛物线梁拱处理 if (dir_Ellipse != "DP") { throw std::runtime_error("参数错误!"); } if (linePara1e.size() != 2) { throw std::runtime_error("参数错误!"); } Point3D_M tp2d; ParsePointLoc(tp2d, linePara1e[1], true); tp2d.m_X += dx; tp2d.m_Y += dy; tp2d.m_Z += dz; newCmdLine = "DP (" + std::to_string(tp2d.m_X) + "," + std::to_string(tp2d.m_Y) + "," + std::to_string(tp2d.m_Z) + ")"; newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); // 梁拱宽度、高度和中心点行 if (commandLines.empty()) { throw std::runtime_error("缺少参数!"); } std::vector linePararw = StringHelper::GetWords(commandLines[0]); if (StringHelper::toUpper(linePararw[0]) != "BFY" || linePararw.size() < 3 || linePararw.size() > 4) { throw std::runtime_error("参数错误!"); } double B = std::stod(linePararw[1]); double f = std::stod(linePararw[2]); double Yc = (linePararw.size() == 4) ? std::stod(linePararw[3]) : 0.0; Yc += dy; if (B == 0 || std::abs(B) < 2 * std::abs(f)) { throw std::runtime_error("梁拱宽度 B 不能为 0,也不能小于梁拱高度 f 的 2 倍!"); } newCmdLine = "BfY " + std::to_string(B) + " " + std::to_string(f) + " " + std::to_string(Yc); newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); // 是否全甲板行 if (!commandLines.empty()) { std::vector str = StringHelper::GetWords(commandLines[0]); if (StringHelper::toUpper(str[0]) == "FULL") { o.m_Full = true; newCmdLine = commandLines[0]; newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); } } } else { throw std::runtime_error("参数错误!"); } break; } default: throw std::runtime_error("不支持的曲线类型!"); } // 重构命令行 std::string newCommand; for (const auto &line : newCommandLines) { newCommand += line + LINE_SPLITTER; } o.m_Command = QString::fromStdString(newCommand); } catch (const std::exception &e) { throw std::runtime_error("原曲线命令行有误,无法复制:" + std::string(e.what())); } return o; } MirrorGeomInterpreter::MirrorGeomInterpreter() { } void MirrorGeomInterpreter::ExecuteCommand(std::vector &commandLines, IModel *&o, DataManager *pdata) { // 旧软件写了一个RedirectExecuteCommand函数,结合文档看 作用未知 // if (commandLines.size() > 1 && StringHelper::toUpper(StringHelper::FirstWord(commandLines[1])) == "SEC") // { // RedirectExecuteCommand(commandLines); // return; // } std::string cmdTmp = ""; std::string name; std::vector lineName = StringHelper::GetWords(commandLines[0]); // 解决指定名称时结果不正确的问题 std::vector pName; std::string lastName = ""; if (lineName.size() == 1) // 未指定名称 { lastName = ""; } else // 指定了名称 { for (size_t i = 1; i < lineName.size(); i++) { lastName = lineName[i]; if (!ParseInputName(name, lastName)) { throw std::runtime_error("命名重复!"); } pName.push_back(name); } } commandLines.erase(commandLines.begin()); if (commandLines.empty()) { throw std::runtime_error("缺少参数!"); } std::vector paraline = StringHelper::GetWords(commandLines[0]); if (StringHelper::toUpper(paraline[0]) != "SOURCE" || paraline.size() < 2) { throw std::runtime_error("参数错误!"); } for (size_t cnt = 1; cnt < paraline.size(); cnt++) { for (size_t cnt1 = cnt + 1; cnt1 < paraline.size(); cnt1++) { if (paraline[cnt] == paraline[cnt1]) { throw std::runtime_error("镜像的图元序列有重复:" + paraline[cnt]); } } } commandLines.erase(commandLines.begin()); // 镜像功能增加镜像面位置 Y double mirrorY = 0; std::vector mirrorline; if (!commandLines.empty()) { mirrorline = StringHelper::GetWords(commandLines[0]); if (StringHelper::toUpper(mirrorline[0]) != "Y" || mirrorline.size() < 2) { throw std::runtime_error("参数错误!"); } // if (!StringHelper::IsDouble(mirrorline[1])) // { // throw std::runtime_error("镜像面位置 Y 应为实数!"); // } mirrorY = std::stod(mirrorline[1]); commandLines.erase(commandLines.begin()); } for (size_t i = 1; i < paraline.size(); i++) { int id = DataManager::GetObjectIDByName(paraline[i]); if (id == -1) { throw std::runtime_error("未找到对象:" + paraline[i]); } IModel *src = DataManager::GetObjectByID(id); // 确定名称 std::string nameStr = ""; if (i - 1 >= pName.size()) // 未指定当前名称 { nameStr = lineName[0]; name = ParseNameMirror(src, nameStr); } else // 指定了一个名称 { name = pName[i - 1]; nameStr = lineName[0] + " " + name; if (typeid(*src) == typeid(Hull)) { std::regex reg_hull(Reg_HULL); if (!std::regex_match(StringHelper::toUpper(name), reg_hull)) { throw std::runtime_error("主船体命名格式不正确!"); } } } // 镜像对象数据 // IModel *o = nullptr; bool bNormalMirror = true; // 是否正常镜像 if (typeid(*src) == typeid(Point3D_M)) { bNormalMirror = false; o = MirrorPoint(static_cast(src), name, 2, mirrorY); o->m_Type = 0; } else if (typeid(*src) == typeid(Curve_M)) { bNormalMirror = false; o = MirrorCurve(static_cast(src), name, 2, mirrorY, pdata); o->m_Type = 10; } else if (typeid(*src) == typeid(Surface_M)) { bNormalMirror = true; Surface_M *oo = new Surface_M(*static_cast(src)); // static_cast(src); oo->m_MirrorDir = 2; // Y 作为镜像面 oo->m_MirrorOrgin = mirrorY; oo->m_Src.resize(ModelData::ARRAY_SIZE_NORMAL); oo->m_Src[0] = src->m_ID; o = oo; o->m_Name = QString::fromStdString(name); o->m_Type = 10; } else if (typeid(*src) == typeid(Solid_M)) { bNormalMirror = true; Solid_M *oo = new Solid_M(*static_cast(src)); // static_cast(src); oo->MirrorDir = 2; // Y 作为镜像面 oo->m_MirrorOrgin = mirrorY; oo->m_Src.resize(ModelData::ARRAY_SIZE_NORMAL); oo->m_Src[0] = src->m_ID; o = oo; o->m_Name = QString::fromStdString(name); o->m_Type = 10; } else if (typeid(*src) == typeid(Hull_M)) { bNormalMirror = true; Hull_M *oo = new Hull_M(*static_cast(src)); // static_cast(src); oo->m_MirrorDir = 2; // Y 作为镜像面 oo->m_MirrorOrgin = mirrorY; oo->m_Src.resize(ModelData::ARRAY_SIZE_NORMAL); oo->m_Src[0] = src->m_ID; o = oo; o->m_Name = QString::fromStdString(name); o->m_Type = 10; } else if (typeid(*src) == typeid(Space_M)) { bNormalMirror = true; Space_M *oo = new Space_M(*static_cast(src)); // static_cast(src); oo->m_MirrorDir = 2; // Y 作为镜像面 oo->m_MirrorOrgin = mirrorY; oo->m_Src.resize(ModelData::ARRAY_SIZE_NORMAL); oo->m_Src[0] = src->m_ID; o = oo; o->m_Name = QString::fromStdString(name); o->m_Type = 10; } else if (typeid(*src) == typeid(Appendage_M)) { bNormalMirror = true; Appendage_M *oo = new Appendage_M(*static_cast(src)); // static_cast(src); oo->m_MirrorDir = 2; // Y 作为镜像面 oo->m_MirrorOrgin = mirrorY; oo->m_Src.resize(ModelData::ARRAY_SIZE_NORMAL); oo->m_Src[0] = src->m_ID; o = oo; o->m_Name = QString::fromStdString(name); o->m_Type = 10; } // 构建命令 std::string cmd; cmd += LINE_SPLITTER + nameStr; cmd += LINE_SPLITTER + paraline[0] + " " + paraline[i]; if (!mirrorline.empty()) { cmd += LINE_SPLITTER + "Y " + mirrorline[1]; } Add2ModelOrInteractWithIdtf(o, bNormalMirror); // 不更改 o->m_Command cmdTmp += cmd; } cmdTmp.clear(); cmdTmp += cmdTmp; } Point3D_M* MirrorGeomInterpreter::MirrorPoint(Point3D_M *srcPoint, std::string &newName, int mirrorDir, double mirrorOrgin) { // 拷贝数据 Point3D_M *o = new Point3D_M(*srcPoint); // 假设 Point3D_M 支持直接拷贝构造 o->m_Name = QString::fromStdString(newName); // 解析命令行,并重构 try { std::vector commandLines = StringHelper::split(srcPoint->m_Command.toStdString(), std::vector{LINE_SPLITTER}); std::vector newCommandLines; // 处理第一行命令 if (commandLines.empty()) { throw std::runtime_error("原图元命令行为空,无法镜像!"); } std::string newCmdLine = "POINT " + o->m_Name.toStdString(); newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); // 参数行 if (commandLines.empty()) { throw std::runtime_error("缺少参数行!"); } std::vector lineLoc = StringHelper::GetWords(commandLines[0]); if (lineLoc.size() < 2 || StringHelper::toUpper(lineLoc[0]) != "LOC") { throw std::runtime_error("参数行格式错误或缺少 LOC 关键字!"); } Point3D_M tp; if (!ParsePointLoc(tp, lineLoc[1], true)) { throw std::runtime_error("参数行坐标解析失败!"); } // 镜像点坐标 tp = PointValueMirror(tp, mirrorDir, mirrorOrgin); o->m_X = tp.m_X; o->m_Y = tp.m_Y; o->m_Z = tp.m_Z; // 构建新的 LOC 行 newCmdLine = "LOC (" + std::to_string(tp.m_X) + "," + std::to_string(tp.m_Y) + "," + std::to_string(tp.m_Z) + ")"; newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); // 重构命令行 std::string newCommand; for (const auto &itemLine : newCommandLines) { newCommand += itemLine + LINE_SPLITTER; } o->m_Command = QString::fromStdString(newCommand); } catch (const std::exception &e) { throw std::runtime_error("原图元命令行有误,无法镜像:" + std::string(e.what())); } return o; } Curve_M* MirrorGeomInterpreter::MirrorCurve(Curve_M *srcCurve, std::string &newName, int mirrorDir, double mirrorOrgin, DataManager *pdata) { CurveInterpreter tmpCurve_Interpreter; // 拷贝数据 Curve_M* o = new Curve_M(*srcCurve); // 假设 Curve_M 支持直接拷贝构造 o->m_Name = QString::fromStdString(newName); o->m_MirrorDir = mirrorDir; o->m_MirrorOrgin = mirrorOrgin; o->m_Src.resize(ModelData::ARRAY_SIZE_NORMAL); o->m_Src[0] = srcCurve->m_ID; // 拷贝节点 std::vector pList; // 节点坐标 if (!srcCurve->m_KnotID.empty()) { o->m_KnotID.resize(ModelData::ARRAY_SIZE_NORMAL); for (size_t i = 0; i < srcCurve->m_KnotID.size(); i++) { int cid = srcCurve->m_KnotID[i]; if (cid == 0) break; Point3D_M *tp = new Point3D_M(*static_cast(DataManager::GetObjectByID(cid))); *tp = PointValueMirror(*tp, mirrorDir, mirrorOrgin); tp->m_ID = GenerateObjectID(tp); tp->m_Type = 0; Add2ModelOrInteractWithIdtf(tp); o->m_KnotID[i] = tp->m_ID; o->m_Src[i + 1] = tp->m_ID; pList.push_back(*tp); } } // 解析命令行,并重构 try { std::vector commandLines = CommandStreamProcessing::SplitCommand(srcCurve->m_Command.toStdString()); std::vector newCommandLines; std::string newCmdLine = StringHelper::toUpper(commandLines[0].substr(0, commandLines[0].find(' '))); // 主命令行 if (newCmdLine == "CURVE") { o->m_Type = 0; } else if (newCmdLine == "ELLIPSE") { o->m_Type = 2; } else if (newCmdLine == "PARABOLA") { o->m_Type = 3; } else { throw std::runtime_error("Unsupported curve type!"); } newCmdLine += " " + o->m_Name.toStdString(); newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); o->m_Full = false; // 根据曲线类型解析参数行 switch (o->m_Type) { case 0: { // 普通曲线 std::vector linePara = StringHelper::GetWords(commandLines[0]); if (StringHelper::toUpper(linePara[0]) == "XYZ") { newCmdLine = StringHelper::toUpper(linePara[0]); o->m_Type = 5; // 节点索引 for (size_t i = 1; i < linePara.size(); i++) { if (linePara[i] == "/-") { // 折点切出 tmpCurve_Interpreter.SetKnotAXYZII(*o, i - 1, 0, 0, 0); o->m_KnotDirII[i - 1] = 2; newCmdLine += " " + linePara[i]; } else if (linePara[i] == "-/") { // 折点切入 tmpCurve_Interpreter.SetKnotAXYZ(*o, i, 0, 0, 0); o->m_KnotDir[i] = 2; newCmdLine += " " + linePara[i]; } else { // 坐标点 Point3D_M tp = pList[i - 1]; newCmdLine += " (" + std::to_string(tp.m_X) + "," + std::to_string(tp.m_Y) + "," + std::to_string(tp.m_Z) + ")"; } } newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); } else if (StringHelper::toUpper(linePara[0]) == "X" || StringHelper::toUpper(linePara[0]) == "Y" || StringHelper::toUpper(linePara[0]) == "Z") { std::string dir1 = StringHelper::toUpper(linePara[0]); Point3D_M tp; // 平面位置行 o->m_Type = 5; double offset = 10000; // 位置面的坐标分量 ParseLoc(linePara, dir1, offset); if (dir1 == "X") { o->m_ProjIDir = 0; if (mirrorDir == 1) offset = 2 * mirrorOrgin - offset; } else if (dir1 == "Y") { o->m_ProjIDir = 1; if (mirrorDir == 2) offset = 2 * mirrorOrgin - offset; } else if (dir1 == "Z") { o->m_ProjIDir = 2; if (mirrorDir == 3) offset = 2 * mirrorOrgin - offset; } else { throw std::runtime_error("参数错误!"); } newCmdLine = dir1 + " " + std::to_string(offset); newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); // 平面坐标序列行 linePara = StringHelper::GetWords(commandLines[0]); newCmdLine = StringHelper::toUpper(linePara[0]); size_t m = 0; // 节点索引 for (size_t i = 1; i < linePara.size(); i++) { if (linePara[i] == "/-") { // 折点切出 tmpCurve_Interpreter.SetKnotAXYZII(*o, m - 1, 0, 0, 0); o->m_KnotDirII[m - 1] = 2; newCmdLine += " " + linePara[i]; } else if (linePara[i] == "-/") { // 折点切入 tmpCurve_Interpreter.SetKnotAXYZ(*o, m, 0, 0, 0); o->m_KnotDir[m] = 2; newCmdLine += " " + linePara[i]; } else { // 节点表达式 tp = pList[m]; if (dir1 == "X") { newCmdLine += " (" + std::to_string(tp.m_Y) + "," + std::to_string(tp.m_Z) + ")"; } else if (dir1 == "Y") { newCmdLine += " (" + std::to_string(tp.m_X) + "," + std::to_string(tp.m_Z) + ")"; } else if (dir1 == "Z") { newCmdLine += " (" + std::to_string(tp.m_X) + "," + std::to_string(tp.m_Y) + ")"; } m++; } } o->m_ProjIKnotCnt = m; newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); } else { throw std::runtime_error("参数行格式错误!"); } break; } case 2: { // 椭圆 std::string dir_Ellipse = ""; double loc_Ellipse = 10000; if (commandLines.empty()) { throw std::runtime_error("缺少参数!"); } // 解析位置面行 std::vector linePara1e = StringHelper::GetWords(commandLines[0]); dir_Ellipse = StringHelper::toUpper(linePara1e[0]); if (dir_Ellipse == "X" || dir_Ellipse == "Y" || dir_Ellipse == "Z") { if (linePara1e.size() != 2) { throw std::runtime_error("参数错误!"); } ParseLoc(linePara1e, linePara1e[0], loc_Ellipse); if (dir_Ellipse == "X") { if (mirrorDir == 1) loc_Ellipse = 2 * mirrorOrgin - loc_Ellipse; } else if (dir_Ellipse == "Y") { if (mirrorDir == 2) loc_Ellipse = 2 * mirrorOrgin - loc_Ellipse; } else if (dir_Ellipse == "Z") { if (mirrorDir == 3) loc_Ellipse = 2 * mirrorOrgin - loc_Ellipse; } newCmdLine = dir_Ellipse + " " + std::to_string(loc_Ellipse); newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); } else if (dir_Ellipse == "DP") { // 梁拱处理 } else { throw std::runtime_error("参数错误!"); } if (commandLines.empty()) { throw std::runtime_error("缺少参数!"); } // 解析中心坐标行 linePara1e = StringHelper::GetWords(commandLines[0]); if (StringHelper::toUpper(linePara1e[0]) == "CENTER") { Point3D_M tp; o->m_Type = 2; int projDir = -1; //投影平面 if (linePara1e.size() != 2) { throw std::runtime_error("参数错误!"); } ParsePointLoc2D(tp, linePara1e[1], dir_Ellipse, loc_Ellipse); tp = PointValueMirror(tp, mirrorDir, mirrorOrgin); o->m_OX = tp.m_X; o->m_OY = tp.m_Y; o->m_OZ = tp.m_Z; o->m_VX = tp.m_X; o->m_VY = tp.m_Y; o->m_VZ = tp.m_Z; if (dir_Ellipse == "X") { o->m_VX += 1; newCmdLine = "CENTER (" + std::to_string(tp.m_Y) + "," + std::to_string(tp.m_Z) + ")"; } else if (dir_Ellipse == "Y") { o->m_VY += 1; newCmdLine = "CENTER (" + std::to_string(tp.m_X) + "," + std::to_string(tp.m_Z) + ")"; } else if (dir_Ellipse == "Z") { o->m_VZ += 1; newCmdLine = "CENTER (" + std::to_string(tp.m_X) + "," + std::to_string(tp.m_Y) + ")"; } newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); // 解析半径行 if (commandLines.empty()) { throw std::runtime_error("缺少参数!"); } std::vector linePara1b = StringHelper::GetWords(commandLines[0]); if (StringHelper::toUpper(linePara1b[0]) != "R" || linePara1b.size() < 2 || linePara1b.size() > 3) { throw std::runtime_error("参数错误!"); } o->m_R1 = std::stod(linePara1b[1]); if (linePara1b.size() == 3) { o->m_R2 = std::stod(linePara1b[2]); if (o->m_R2 < 0) { throw std::runtime_error("椭圆弧半径(R2)应为正实数"); } } else { o->m_R2 = o->m_R1; } if (o->m_R1 <= 0 || o->m_R2 <= 0) { throw std::runtime_error("椭圆弧半径应大于 0!"); } newCmdLine = commandLines[0]; newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); // 解析角度行 o->m_A1 = 0; o->m_A2 = 360; if (!commandLines.empty()) { std::vector lineParaagl = StringHelper::GetWords(commandLines[0]); if (StringHelper::toUpper(lineParaagl[0]) != "ANGLE") { throw std::runtime_error("参数错误!"); } if (lineParaagl.size() != 3) { throw std::runtime_error("参数错误!"); } o->m_A1 = std::stod(lineParaagl[1]); o->m_A2 = std::stod(lineParaagl[2]); if (o->m_A1 < -360 || o->m_A1 > 360 || o->m_A2 < -360 || o->m_A2 > 360) { throw std::runtime_error("椭圆弧角度值范围应为 [-360, 360]!"); } else if (o->m_A1 >= o->m_A2) { throw std::runtime_error("椭圆弧起始角度应小于终止角度!"); } newCmdLine = commandLines[0]; newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); } } else if (StringHelper::toUpper(linePara1e[0]) == "LOC") { // 三点处理 o->m_Type = 7; if (linePara1e.size() != 4) { throw std::runtime_error("参数错误!"); } Point3D_M tp2d1 = pList[0]; o->m_P1X = tp2d1.m_X; o->m_P1Y = tp2d1.m_Y; o->m_P1Z = tp2d1.m_Z; Point3D_M tp2d2 = pList[1]; o->m_OX = tp2d2.m_X; o->m_OY = tp2d2.m_Y; o->m_OZ = tp2d2.m_Z; Point3D_M tp2d3 = pList[2]; o->m_P2X = tp2d3.m_X; o->m_P2Y = tp2d3.m_Y; o->m_P2Z = tp2d3.m_Z; newCmdLine = "LOC"; if (dir_Ellipse == "X") { for (int k = 0; k < 3; k++) { Point3D_M tp = pList[k]; newCmdLine += " (" + std::to_string(tp.m_Y) + "," + std::to_string(tp.m_Z) + ")"; } } else if (dir_Ellipse == "Y") { for (int k = 0; k < 3; k++) { Point3D_M tp = pList[k]; newCmdLine += " (" + std::to_string(tp.m_X) + "," + std::to_string(tp.m_Z) + ")"; } } else if (dir_Ellipse == "Z") { for (int k = 0; k < 3; k++) { Point3D_M tp = pList[k]; newCmdLine += " (" + std::to_string(tp.m_X) + "," + std::to_string(tp.m_Y) + ")"; } } newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); } else if (dir_Ellipse == "DP") { // 梁拱处理 o->m_Type = 2; if (linePara1e.size() != 2) { throw std::runtime_error("参数错误!"); } Point3D_M tp2d; ParsePointLoc(tp2d, linePara1e[1], true); tp2d = PointValueMirror(tp2d, mirrorDir, mirrorOrgin); newCmdLine = "DP (" + std::to_string(tp2d.m_X) + "," + std::to_string(tp2d.m_Y) + "," + std::to_string(tp2d.m_Z) + ")"; newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); // 梁拱宽度、高度和中心点行 if (commandLines.empty()) { throw std::runtime_error("缺少参数!"); } std::vector linePararw = StringHelper::GetWords(commandLines[0]); if (StringHelper::toUpper(linePararw[0]) != "BFY" || linePararw.size() < 3 || linePararw.size() > 4) { throw std::runtime_error("参数错误!"); } double B = std::stod(linePararw[1]); double f = std::stod(linePararw[2]); double Yc = (linePararw.size() == 4) ? std::stod(linePararw[3]) : 0.0; if (B == 0 || std::abs(B) < 2 * std::abs(f)) { throw std::runtime_error("梁拱宽度 B 不能为 0,也不能小于梁拱高度 f 的 2 倍!"); } newCmdLine = "BfY " + std::to_string(B) + " " + std::to_string(f) + " " + std::to_string(Yc); newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); // 是否全甲板行 if (!commandLines.empty()) { std::vector str = StringHelper::GetWords(commandLines[0]); if (StringHelper::toUpper(str[0]) == "FULL") { o->m_Full = true; newCmdLine = commandLines[0]; newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); } } // 重新计算圆心位置 Point3D_M tp; tp.m_X = o->m_OX; tp.m_Y = o->m_OY; tp.m_Z = o->m_OZ; tp = PointValueMirror(tp, mirrorDir, mirrorOrgin); o->m_OX = tp.m_X; o->m_OY = tp.m_Y; o->m_OZ = tp.m_Z; } else { throw std::runtime_error("参数错误!"); } break; } case 3: { std::vector linePara1e = StringHelper::GetWords(commandLines[0]); std::string dir_Ellipse = StringHelper::toUpper(linePara1e[0]); double loc_Ellipse = 0; if (dir_Ellipse == "X" || dir_Ellipse == "Y" || dir_Ellipse == "Z") { if (linePara1e.size() != 2) { throw std::runtime_error("参数错误!"); } ParseLoc(linePara1e, linePara1e[0], loc_Ellipse); if (dir_Ellipse == "X") { if (mirrorDir == 1) loc_Ellipse = 2 * mirrorOrgin - loc_Ellipse; } else if (dir_Ellipse == "Y") { if (mirrorDir == 2) loc_Ellipse = 2 * mirrorOrgin - loc_Ellipse; } else if (dir_Ellipse == "Z") { if (mirrorDir == 3) loc_Ellipse = 2 * mirrorOrgin - loc_Ellipse; } newCmdLine = dir_Ellipse + " " + std::to_string(loc_Ellipse); newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); } else if (dir_Ellipse == "DP") { // 梁拱处理 } else { throw std::runtime_error("参数错误!"); } if (commandLines.empty()) { throw std::runtime_error("缺少参数!"); } // 解析 LOC 或 DP 行 linePara1e = StringHelper::GetWords(commandLines[0]); if (StringHelper::toUpper(linePara1e[0]) == "LOC") { // 三点抛物线处理 if (linePara1e.size() != 4) { throw std::runtime_error("参数错误!"); } Point3D_M tp2d1 = pList[0]; o->m_P1X = tp2d1.m_X; o->m_P1Y = tp2d1.m_Y; o->m_P1Z = tp2d1.m_Z; Point3D_M tp2d2 = pList[1]; o->m_OX = tp2d2.m_X; o->m_OY = tp2d2.m_Y; o->m_OZ = tp2d2.m_Z; Point3D_M tp2d3 = pList[2]; o->m_P2X = tp2d3.m_X; o->m_P2Y = tp2d3.m_Y; o->m_P2Z = tp2d3.m_Z; newCmdLine = "LOC"; if (dir_Ellipse == "X") { for (int k = 0; k < 3; k++) { Point3D_M tp = pList[k]; newCmdLine += " (" + std::to_string(tp.m_Y) + "," + std::to_string(tp.m_Z) + ")"; } } else if (dir_Ellipse == "Y") { for (int k = 0; k < 3; k++) { Point3D_M tp = pList[k]; newCmdLine += " (" + std::to_string(tp.m_X) + "," + std::to_string(tp.m_Z) + ")"; } } else if (dir_Ellipse == "Z") { for (int k = 0; k < 3; k++) { Point3D_M tp = pList[k]; newCmdLine += " (" + std::to_string(tp.m_X) + "," + std::to_string(tp.m_Y) + ")"; } } newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); } else if (StringHelper::toUpper(linePara1e[0]) == "DP") { // 抛物线梁拱处理 if (dir_Ellipse != "DP") { throw std::runtime_error("参数错误!"); } if (linePara1e.size() != 2) { throw std::runtime_error("参数错误!"); } Point3D_M tp2d; ParsePointLoc(tp2d, linePara1e[1], true); tp2d = PointValueMirror(tp2d, mirrorDir, mirrorOrgin); newCmdLine = "DP (" + std::to_string(tp2d.m_X) + "," + std::to_string(tp2d.m_Y) + "," + std::to_string(tp2d.m_Z) + ")"; newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); // 梁拱宽度、高度和中心点行 if (commandLines.empty()) { throw std::runtime_error("缺少参数!"); } std::vector linePararw = StringHelper::GetWords(commandLines[0]); if (StringHelper::toUpper(linePararw[0]) != "BFY" || linePararw.size() < 3 || linePararw.size() > 4) { throw std::runtime_error("参数错误!"); } double B = std::stod(linePararw[1]); double f = std::stod(linePararw[2]); double Yc = (linePararw.size() == 4) ? std::stod(linePararw[3]) : 0.0; if (B == 0 || std::abs(B) < 2 * std::abs(f)) { throw std::runtime_error("梁拱宽度 B 不能为 0,也不能小于梁拱高度 f 的 2 倍!"); } newCmdLine = "BfY " + std::to_string(B) + " " + std::to_string(f) + " " + std::to_string(Yc); newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); // 是否全甲板行 if (!commandLines.empty()) { std::vector str = StringHelper::GetWords(commandLines[0]); if (StringHelper::toUpper(str[0]) == "FULL") { o->m_Full = true; newCmdLine = commandLines[0]; newCommandLines.push_back(newCmdLine); commandLines.erase(commandLines.begin()); } } } else { throw std::runtime_error("参数错误!"); } break; } default: throw std::runtime_error("Unsupported curve type!"); } // 重构命令行 std::string newCommand; for (const auto &line : newCommandLines) { newCommand += line + LINE_SPLITTER; } o->m_Command = QString::fromStdString(newCommand); } catch (const std::exception &e) { throw std::runtime_error("原图元命令行有误,无法镜像: " + std::string(e.what())); } return o; } Point3D_M MirrorGeomInterpreter::PointValueMirror(const Point3D_M& srcPoint, int mirrorDir, double mirrorOrgin) { Point3D_M tp; tp.m_X = srcPoint.m_X; tp.m_Y = srcPoint.m_Y; tp.m_Z = srcPoint.m_Z; switch (mirrorDir) { case 1: tp.m_X = 2 * mirrorOrgin - srcPoint.m_X; break; case 2: tp.m_Y = 2 * mirrorOrgin - srcPoint.m_Y; break; case 3: tp.m_Z = 2 * mirrorOrgin - srcPoint.m_Z; break; default: throw std::invalid_argument("Invalid mirrorDir value"); } return tp; } JoinGeomInterpreter::JoinGeomInterpreter() { } void JoinGeomInterpreter::ExecuteCommand(std::vector &commandLines, IModel *&o, std::vector &toDel, std::vector& names) { // Implementation of the command execution // 现有文档和资料不知道这个SEC是什么,暂时注释掉 // if (commandLines.size() > 1 && StringHelper::toUpper(StringHelper::FirstWord(commandLines[1])) == "SEC") { // RedirectExecuteCommand(commandLines); // return; // } // 名称行 std::string name; std::string nameline = commandLines[0]; commandLines.erase(commandLines.begin()); if (commandLines.empty()) { throw std::runtime_error("缺少参数!"); } std::vector paraline = StringHelper::GetWords(commandLines[0]); if (StringHelper::toUpper(paraline[0]) != "SOURCE" || paraline.size() < 2) { throw std::runtime_error("参数错误!"); } std::type_info const *t = nullptr; for (size_t i = 1; i < paraline.size(); i++) { int id = DataManager::GetGeomObjectIDByName(paraline[i]); if (id == -1) { throw std::runtime_error("未找到对象:" + paraline[i]); } toDel.push_back(id); names.push_back(paraline[i]); const std::type_info &tt = typeid(*DataManager::GetObjectByID(id)); if (t != nullptr) { if (*t != tt) { throw std::runtime_error("拼接源图元类型不一致!"); } } else { t = &tt; if (*t == typeid(Curve_M)) { o = new Curve_M(); } else if (*t == typeid(Surface_M)) { o = new Surface_M(); } else { throw std::runtime_error("拼接源图元类型只能为\"线\"或\"面\"!"); } } int newid = id; // CopyObjectWithSrc(id).ID; o->m_Src.resize(ModelData::ARRAY_SIZE_NORMAL); o->m_Src[i - 1] = newid; } if (!ParseName(*o, name, nameline)) { throw std::runtime_error("命名重复!"); } o->m_Type = 11; o->m_Name = QString::fromStdString(name); commandLines.erase(commandLines.begin()); Add2ModelOrInteractWithIdtf(o); if (!commandLines.empty() && StringHelper::toUpper(StringHelper::FirstWord(commandLines[0])) == "DELSRC") { } else { names.clear(); toDel.clear(); } } TrimInterpreter::TrimInterpreter() { } void TrimInterpreter::ExecuteCommand(std::vector &commandLines, IModel *&o) { // 检查命令是否为空 if (commandLines.empty()) { throw std::runtime_error("缺少参数!"); } // 名称行 std::string nameline = commandLines[0]; commandLines.erase(commandLines.begin()); // SOURCE std::vector paraline = StringHelper::GetWords(commandLines[0]); if (StringHelper::toUpper(paraline[0]) != "SOURCE" || paraline.size() != 2) { throw std::runtime_error("参数错误!"); } std::string srcname = paraline[1]; int srcid = DataManager::GetGeomObjectIDByName(srcname); if (srcid == -1) { throw std::runtime_error("未找到对象:" + srcname); } IModel *srcObj = DataManager::GetObjectByID(srcid); const std::type_info &t = typeid(*srcObj); // 根据类型分配内存 if (t == typeid(Curve_M)) { o = new Curve_M(); } else if (t == typeid(Surface_M)) { int srcType = srcObj->m_Type; if (srcType == 5 || srcType == 4) { throw std::runtime_error("管道面、球面不参与剪切!"); } o = new Surface_M(); } else if (t == typeid(Solid_M)) { o = new Solid_M(); } // 解析名称 std::string name; if (!ParseName(*o, name, nameline)) { throw std::runtime_error("命名重复!"); } o->m_Name = QString::fromStdString(name); int newid = srcid; o->m_Src.resize(ModelData::ARRAY_SIZE_NORMAL); o->m_Src[0] = newid; commandLines.erase(commandLines.begin()); // 处理 BY 命令 if (commandLines.empty()) { throw std::runtime_error("缺少参数!"); } paraline = StringHelper::GetWords(commandLines[0]); if (StringHelper::toUpper(paraline[0]) != "BY" || paraline.size() != 2) { throw std::runtime_error("参数错误!"); } std::string spstr = paraline[1]; if (t == typeid(Curve_M)) { Point3D_M tp; if (!ParsePointLoc(tp, spstr, true)) { throw std::runtime_error("参数错误!"); } Curve_M *curve = dynamic_cast(o); curve->m_SplitX = tp.m_X; curve->m_SplitY = tp.m_Y; curve->m_SplitZ = tp.m_Z; curve->m_OX = tp.m_X; curve->m_OY = tp.m_Y; curve->m_OZ = tp.m_Z; } else { int spid = DataManager::GetGeomObjectIDByName(spstr); if (spid == -1) { throw std::runtime_error("未找到对象:" + spstr); } IModel *m = DataManager::GetObjectByID(spid); const std::type_info &tt = typeid(*m); if (t == typeid(Curve_M) && tt == typeid(Point3D_M)) { Point3D_M *tp = dynamic_cast(m); Curve_M *curve = dynamic_cast(o); curve->m_SplitX = tp->m_X; curve->m_SplitY = tp->m_Y; curve->m_SplitZ = tp->m_Z; curve->m_OX = tp->m_X; curve->m_OY = tp->m_Y; curve->m_OZ = tp->m_Z; } else if ((t == typeid(Surface_M) && tt == typeid(Surface_M)) || (t == typeid(Solid_M) && tt == typeid(Surface_M))) { int newspid = spid; o->m_Src[1] = newspid; } else { throw std::runtime_error("图元类型错误!"); } } commandLines.erase(commandLines.begin()); // 处理 SAVEP 命令 if (t == typeid(Curve_M) || t == typeid(Surface_M) || t == typeid(Solid_M)) { if (commandLines.empty()) { throw std::runtime_error("缺少参数!"); } paraline = StringHelper::GetWords(commandLines[0]); if (StringHelper::toUpper(paraline[0]) != "SAVEP" || paraline.size() != 2) { throw std::runtime_error("参数错误!"); } Point3D_M p; if (!ParsePointLoc(p, paraline[1], true)) { throw std::runtime_error("参数错误!"); } // 设置修剪点 if (t == typeid(Curve_M)) { Curve_M *curve = dynamic_cast(o); curve->m_TrimX = p.m_X; curve->m_TrimY = p.m_Y; curve->m_TrimZ = p.m_Z; curve->m_P1X = p.m_X; curve->m_P1Y = p.m_Y; curve->m_P1Z = p.m_Z; } else if (t == typeid(Surface_M)) { Surface_M *surface = dynamic_cast(o); surface->m_TrimX = p.m_X; surface->m_TrimY = p.m_Y; surface->m_TrimZ = p.m_Z; // surface->m_P1X = p.m_X; // surface->m_P1Y = p.m_Y; // surface->m_P1Z = p.m_Z; } else if (t == typeid(Solid_M)) { Solid_M *solid = dynamic_cast(o); solid->m_TrimX = p.m_X; solid->m_TrimY = p.m_Y; solid->m_TrimZ = p.m_Z; // solid->m_P1X = p.m_X; // solid->m_P1Y = p.m_Y; // solid->m_P1Z = p.m_Z; } commandLines.erase(commandLines.begin()); } o->m_Type = 12; // 表示修剪 Add2ModelOrInteractWithIdtf(o); } IntersectInterpreter::IntersectInterpreter() { } void IntersectInterpreter::ExecuteCommand(std::vector &commandLines, IModel &o) { o = Curve_M(); // 名称行 std::string name; std::string cmd = commandLines[0]; if (!ParseName(o, name, cmd)) { throw std::runtime_error("命名重复!"); } o.m_Name = QString::fromStdString(name); commandLines.erase(commandLines.begin()); if (commandLines.empty()) { throw std::runtime_error("缺少参数!"); } std::vector paraline = StringHelper::GetWords(commandLines[0]); if (StringHelper::toUpper(paraline[0]) != "BETWEEN" || paraline.size() != 3) { throw std::runtime_error("参数错误!"); } o.m_Src.resize(ModelData::ARRAY_SIZE_NORMAL); int id1 = DataManager::GetObjectIDByName(paraline[1]); if (id1 == -1) { throw std::runtime_error("未找到对象:" + paraline[1]); } int newid1 = id1; // CopyObjectWithSrc(id1).ID; o.m_Src[0] = newid1; int id2 = DataManager::GetObjectIDByName(paraline[2]); if (id2 == -1) { throw std::runtime_error("未找到对象:" + paraline[2]); } int newid2 = id2; // CopyObjectWithSrc(id2).ID; o.m_Src[1] = newid2; commandLines.erase(commandLines.begin()); o.m_Type = 13; // 表示交集 Add2ModelOrInteractWithIdtf(&o); }