COMPASSi/trunk/code/projects/DataManager/Logic/Logic.DataManagement/Interpreters/EditGeomInterpreter.cpp

2219 lines
76 KiB
C++
Raw Normal View History

2025-06-25 15:06:42 +08:00
#include "EditGeomInterpreter.h"
#include "CurveInterpreter.h"
#include "Constants.h"
#include "DataManager.h"
#include <algorithm>
#include <stdexcept>
#include <cmath> // For mathematical operations like std::abs and std::sqrt
#include <limits> // For std::numeric_limits
#include <regex>
#include "DataManagerGlobal.h"
#include "Common/tangible_string_helper.h"
#include "Interfaces.h"
#include "CommandStreamProcessing.h"
CopyInterpreter::CopyInterpreter()
{
}
void CopyInterpreter::ExecuteCommand(std::vector<std::string> &commandLines, IModel *&o)
{
// XUEFENG ADDED 202201
bool OnlyOneName = false;
// END ADDED
// 名称行
std::string cmdTmp = "";
std::vector<std::string> lineName = StringHelper::GetWords(commandLines[0]);
commandLines.erase(commandLines.begin());
if (commandLines.empty())
{
throw std::runtime_error("缺少参数!");
}
// 解析 SOURCE 行
std::vector<std::string> 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<std::string> offsetline = StringHelper::GetWords(commandLines[0]);
if (StringHelper::toUpper(offsetline[0]) != "OFFSET" || offsetline.size() != 2)
{
throw std::runtime_error("缺少关键字 OFFSET 或偏移量格式不正确!");
}
std::vector<std::string> s = StringHelper::split(
StringHelper::replace(
StringHelper::replace(offsetline[1], "(", ""),
")", ""),
std::vector<std::string>{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<Point3D_M *>(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<Curve_M *>(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<Surface_M *>(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<Solid_M *>(src)); // static_cast<Solid_M *>(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<Hull_M *>(src)); // static_cast<Hull_M *>(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<Space_M *>(src)); // static_cast<Space_M *>(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<Appendage_M *>(src)); // static_cast<Appendage_M *>(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<std::string> commandLines = StringHelper::split(srcPoint.m_Command.toStdString(), std::vector<std::string>{LINE_SPLITTER});
std::vector<std::string> 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<std::string> 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<Point3D_M> 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<Point3D_M *>(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<std::string> commandLines = StringHelper::split(srcCurve.m_Command.toStdString(), std::vector<std::string>{LINE_SPLITTER});
std::vector<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> &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<std::string> lineName = StringHelper::GetWords(commandLines[0]);
// 解决指定名称时结果不正确的问题
std::vector<std::string> 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<std::string> 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<std::string> 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<Point3D_M*>(src), name, 2, mirrorY);
o->m_Type = 0;
}
else if (typeid(*src) == typeid(Curve_M))
{
bNormalMirror = false;
o = MirrorCurve(static_cast<Curve_M*>(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<Surface_M *>(src)); // static_cast<Surface_M *>(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<Solid_M *>(src)); // static_cast<Solid_M *>(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<Hull_M *>(src)); // static_cast<Hull_M *>(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<Space_M *>(src)); // static_cast<Space_M *>(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<Appendage_M *>(src)); // static_cast<Appendage_M *>(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<std::string> commandLines = StringHelper::split(srcPoint->m_Command.toStdString(), std::vector<std::string>{LINE_SPLITTER});
std::vector<std::string> 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<std::string> 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<Point3D_M> 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<Point3D_M *>(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<std::string> commandLines = CommandStreamProcessing::SplitCommand(srcCurve->m_Command.toStdString());
std::vector<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> &commandLines, IModel *&o, std::vector<int> &toDel, std::vector<std::string>& names)
{
// Implementation of the command execution
// 现有文档和资料不知道这个SEC是什么暂时注释掉
// if (commandLines.size() > 1 && StringHelper::toUpper(StringHelper::FirstWord(commandLines[1])) == "SEC") {
// RedirectExecuteCommand<JoinSecInterpreter>(commandLines);
// return;
// }
// 名称行
std::string name;
std::string nameline = commandLines[0];
commandLines.erase(commandLines.begin());
if (commandLines.empty())
{
throw std::runtime_error("缺少参数!");
}
std::vector<std::string> 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<std::string> &commandLines, IModel *&o)
{
// 检查命令是否为空
if (commandLines.empty())
{
throw std::runtime_error("缺少参数!");
}
// 名称行
std::string nameline = commandLines[0];
commandLines.erase(commandLines.begin());
// SOURCE
std::vector<std::string> 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<Curve_M *>(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<Point3D_M *>(m);
Curve_M *curve = dynamic_cast<Curve_M *>(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<Curve_M *>(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<Surface_M *>(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<Solid_M *>(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<std::string> &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<std::string> 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);
}