2219 lines
76 KiB
C++
2219 lines
76 KiB
C++
#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);
|
||
}
|