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

2219 lines
76 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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);
}