515 lines
14 KiB
C++
515 lines
14 KiB
C++
|
#include "SolidInterpreter.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 "Geometry_M.h"
|
||
|
#include "Common/tangible_string_helper.h"
|
||
|
|
||
|
SolidInterpreter::SolidInterpreter()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void SolidInterpreter::ExecuteCommand(std::vector<std::string> &commandLines, Solid_M &o)
|
||
|
{
|
||
|
if (commandLines.empty())
|
||
|
{
|
||
|
throw std::runtime_error("Missing command lines.");
|
||
|
}
|
||
|
o.m_Src.resize(ModelData::ARRAY_SIZE_NORMAL);
|
||
|
o.m_BoolMode.resize(ModelData::ARRAY_SIZE_NORMAL);
|
||
|
std::string firstWord = StringHelper::toUpper(StringHelper::FirstWord(commandLines[0]));
|
||
|
if (firstWord == "SOLID")
|
||
|
o.m_Type = 0;
|
||
|
else if (firstWord == "SWEEPSOLID")
|
||
|
o.m_Type = 1;
|
||
|
else if (firstWord == "ROTATIONSOLID")
|
||
|
o.m_Type = 2;
|
||
|
else if (firstWord == "SPHERESOLID")
|
||
|
o.m_Type = 3;
|
||
|
else if (firstWord == "CYLINDERSOLID")
|
||
|
o.m_Type = 4;
|
||
|
else if (firstWord == "RTANKSOLID")
|
||
|
o.m_Type = 5;
|
||
|
else if (firstWord == "BOX")
|
||
|
o.m_Type = 6;
|
||
|
else
|
||
|
{
|
||
|
throw std::runtime_error("Unknown solid type.");
|
||
|
}
|
||
|
|
||
|
std::string name;
|
||
|
if (!ParseName(o, name, commandLines[0]))
|
||
|
{
|
||
|
throw std::runtime_error("命令执行失败\n Error: 重复命名,不能覆盖原名称对象.\n 位置:行 " + commandLines[0] + "\n 后续命令未执行"); // 解决命名重复的问题
|
||
|
}
|
||
|
o.m_Name = QString::fromStdString(name);
|
||
|
LineDone(commandLines);
|
||
|
|
||
|
switch (o.m_Type)
|
||
|
{
|
||
|
case 0:
|
||
|
SOLID(commandLines, o);
|
||
|
break;
|
||
|
case 1:
|
||
|
SWEEPSOLID(commandLines, o);
|
||
|
break;
|
||
|
case 2:
|
||
|
ROTATIONSOLID(commandLines, o);
|
||
|
break;
|
||
|
case 3:
|
||
|
SPHERESOLID(commandLines, o);
|
||
|
break;
|
||
|
case 4:
|
||
|
CYLINDERSOLID(commandLines, o);
|
||
|
break;
|
||
|
case 5:
|
||
|
RTANKSOLID(commandLines, o);
|
||
|
break;
|
||
|
case 6:
|
||
|
BOX(commandLines, o);
|
||
|
break;
|
||
|
default:
|
||
|
throw std::runtime_error("Invalid solid type.");
|
||
|
}
|
||
|
|
||
|
Add2ModelOrInteractWithIdtf(&o);
|
||
|
}
|
||
|
|
||
|
void SolidInterpreter::BOX(std::vector<std::string> &commandLines, Solid_M &o)
|
||
|
{
|
||
|
if (commandLines.empty())
|
||
|
{
|
||
|
throw std::runtime_error("Missing command lines.");
|
||
|
}
|
||
|
|
||
|
auto lineParaCENTER = StringHelper::GetWords(commandLines[0]);
|
||
|
if (lineParaCENTER[0] != "CENTER" || lineParaCENTER.size() != 2)
|
||
|
{
|
||
|
throw std::runtime_error("ErrorParameterException: Missing parameters.");
|
||
|
}
|
||
|
|
||
|
Point3D_M center;
|
||
|
if (!ParsePointLoc(center, lineParaCENTER[1]))
|
||
|
{
|
||
|
throw std::runtime_error("ErrorParameterException: Invalid parameters.");
|
||
|
}
|
||
|
o.m_OX = center.m_X;
|
||
|
o.m_OY = center.m_Y;
|
||
|
o.m_OZ = center.m_Z;
|
||
|
|
||
|
LineDone(commandLines);
|
||
|
|
||
|
if (commandLines.empty())
|
||
|
{
|
||
|
throw std::runtime_error("Missing command lines.");
|
||
|
}
|
||
|
|
||
|
auto lineParaRO = StringHelper::GetWords(commandLines[0]);
|
||
|
if (lineParaRO[0] != "LBH" || lineParaRO.size() != 4)
|
||
|
{
|
||
|
throw std::runtime_error("ErrorParameterException: Missing parameters.");
|
||
|
}
|
||
|
|
||
|
o.m_L = std::stod(lineParaRO[1]);
|
||
|
o.m_B = std::stod(lineParaRO[2]);
|
||
|
o.m_H = std::stod(lineParaRO[3]);
|
||
|
|
||
|
if (o.m_L <= 0)
|
||
|
{
|
||
|
throw std::runtime_error("长度要大于0。");
|
||
|
}
|
||
|
if (o.m_B <= 0)
|
||
|
{
|
||
|
throw std::runtime_error("宽度度要大于0。");
|
||
|
}
|
||
|
if (o.m_H <= 0)
|
||
|
{
|
||
|
throw std::runtime_error("高度要大于0。");
|
||
|
}
|
||
|
|
||
|
LineDone(commandLines);
|
||
|
}
|
||
|
|
||
|
void SolidInterpreter::RTANKSOLID(std::vector<std::string> &commandLines, Solid_M &o)
|
||
|
{
|
||
|
if (commandLines.empty())
|
||
|
{
|
||
|
throw std::runtime_error("Missing command lines.");
|
||
|
}
|
||
|
|
||
|
auto lineParaCENTER = StringHelper::GetWords(commandLines[0]);
|
||
|
if (lineParaCENTER[0] != "CENTER" || lineParaCENTER.size() != 3)
|
||
|
{
|
||
|
throw std::runtime_error("ErrorParameterException: Missing parameters.");
|
||
|
}
|
||
|
|
||
|
Point3D_M center;
|
||
|
if (!ParsePointLoc(center, lineParaCENTER[1]))
|
||
|
{
|
||
|
throw std::runtime_error("ErrorParameterException: Invalid parameters.");
|
||
|
}
|
||
|
o.m_OX = center.m_X;
|
||
|
o.m_OY = center.m_Y;
|
||
|
o.m_OZ = center.m_Z;
|
||
|
|
||
|
if (!ParsePointLoc(center, lineParaCENTER[2]))
|
||
|
{
|
||
|
throw std::runtime_error("ErrorParameterException: Invalid parameters.");
|
||
|
}
|
||
|
o.m_PX = center.m_X;
|
||
|
o.m_PY = center.m_Y;
|
||
|
o.m_PZ = center.m_Z;
|
||
|
|
||
|
if (std::abs(o.m_OX - o.m_PX) + std::abs(o.m_OY - o.m_PY) + std::abs(o.m_OZ - o.m_PZ) <= 0)
|
||
|
{
|
||
|
throw std::runtime_error("圆心不能重合");
|
||
|
}
|
||
|
|
||
|
LineDone(commandLines);
|
||
|
|
||
|
if (commandLines.empty())
|
||
|
{
|
||
|
std::runtime_error("Missing command lines.");
|
||
|
}
|
||
|
|
||
|
auto lineParaRO = StringHelper::GetWords(commandLines[0]);
|
||
|
if (lineParaRO[0] != "RH" || (lineParaRO.size() != 3 && lineParaRO.size() != 2))
|
||
|
{
|
||
|
std::runtime_error("ErrorParameterException: Missing parameters.");
|
||
|
}
|
||
|
|
||
|
center = Point3D_M();
|
||
|
ParsePointLoc2D(center, lineParaRO[1], "X", 0);
|
||
|
o.m_AR = center.m_Y;
|
||
|
o.m_H = center.m_Z;
|
||
|
|
||
|
if(o.m_AR < 0)
|
||
|
{
|
||
|
throw std::runtime_error("半径要大于等于0。");
|
||
|
|
||
|
}
|
||
|
if (o.m_H <= 0)
|
||
|
{
|
||
|
throw std::runtime_error("高度要大于0。");
|
||
|
}
|
||
|
|
||
|
if (lineParaRO.size() == 3)
|
||
|
{
|
||
|
center = Point3D_M();
|
||
|
ParsePointLoc2D(center, lineParaRO[2], "X", 0);
|
||
|
o.m_AR1 = center.m_Y;
|
||
|
o.m_H1 = center.m_Z;
|
||
|
if (o.m_AR1 < 0)
|
||
|
{
|
||
|
throw std::runtime_error("半径要大于等于0。");
|
||
|
}
|
||
|
if (o.m_H1 <= 0)
|
||
|
{
|
||
|
throw std::runtime_error("高度要大于0。");
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
o.m_AR1 = o.m_AR;
|
||
|
o.m_H1 = o.m_H;
|
||
|
}
|
||
|
|
||
|
LineDone(commandLines);
|
||
|
}
|
||
|
|
||
|
void SolidInterpreter::CYLINDERSOLID(std::vector<std::string> &commandLines, Solid_M &o)
|
||
|
{
|
||
|
if (commandLines.empty())
|
||
|
{
|
||
|
throw std::runtime_error("Missing command lines.");
|
||
|
}
|
||
|
|
||
|
auto lineParaCENTER = StringHelper::GetWords(commandLines[0]);
|
||
|
if (lineParaCENTER[0] != "CENTER" || lineParaCENTER.size() != 3)
|
||
|
{
|
||
|
throw std::runtime_error("ErrorParameterException: Missing parameters.");
|
||
|
}
|
||
|
|
||
|
Point3D_M center;
|
||
|
if (!ParsePointLoc(center, lineParaCENTER[1]))
|
||
|
{
|
||
|
throw std::runtime_error("ErrorParameterException: Invalid parameters.");
|
||
|
}
|
||
|
o.m_OX = center.m_X;
|
||
|
o.m_OY = center.m_Y;
|
||
|
o.m_OZ = center.m_Z;
|
||
|
|
||
|
if (!ParsePointLoc(center, lineParaCENTER[2]))
|
||
|
{
|
||
|
throw std::runtime_error("ErrorParameterException: Invalid parameters.");
|
||
|
}
|
||
|
o.m_PX = center.m_X;
|
||
|
o.m_PY = center.m_Y;
|
||
|
o.m_PZ = center.m_Z;
|
||
|
|
||
|
if (std::abs(o.m_OX - o.m_PX) + std::abs(o.m_OY - o.m_PY) + std::abs(o.m_OZ - o.m_PZ) <= 0)
|
||
|
{
|
||
|
throw std::runtime_error("圆心不能重合");
|
||
|
}
|
||
|
|
||
|
LineDone(commandLines);
|
||
|
|
||
|
if (commandLines.empty())
|
||
|
{
|
||
|
throw std::runtime_error("Missing command lines.");
|
||
|
}
|
||
|
|
||
|
auto lineParaRO = StringHelper::GetWords(commandLines[0]);
|
||
|
if (lineParaRO[0] != "R" || lineParaRO.size() != 3)
|
||
|
{
|
||
|
throw std::runtime_error("ErrorParameterException: Missing parameters.");
|
||
|
}
|
||
|
|
||
|
o.m_AR = std::stod(lineParaRO[1]);
|
||
|
o.m_AR1 = std::stod(lineParaRO[2]);
|
||
|
|
||
|
if (o.m_AR <= 0 || o.m_AR1 <= 0)
|
||
|
{
|
||
|
throw std::runtime_error("半径要大于0。");
|
||
|
}
|
||
|
|
||
|
LineDone(commandLines);
|
||
|
}
|
||
|
|
||
|
void SolidInterpreter::SPHERESOLID(std::vector<std::string> &commandLines, Solid_M &o)
|
||
|
{
|
||
|
if (commandLines.empty())
|
||
|
{
|
||
|
throw std::runtime_error("Missing command lines.");
|
||
|
}
|
||
|
|
||
|
auto lineParaCENTER = StringHelper::GetWords(commandLines[0]);
|
||
|
if (lineParaCENTER[0] != "CENTER" || (lineParaCENTER.size() != 2 && lineParaCENTER.size() != 3))
|
||
|
{
|
||
|
throw std::runtime_error("ErrorParameterException: Missing parameters.");
|
||
|
}
|
||
|
|
||
|
Point3D_M center;
|
||
|
if (!ParsePointLoc(center, lineParaCENTER[1]))
|
||
|
{
|
||
|
throw std::runtime_error("ErrorParameterException: Invalid parameters.");
|
||
|
}
|
||
|
o.m_OX = center.m_X;
|
||
|
o.m_OY = center.m_Y;
|
||
|
o.m_OZ = center.m_Z;
|
||
|
|
||
|
if (lineParaCENTER.size() == 3)
|
||
|
{
|
||
|
if (!ParsePointLoc(center, lineParaCENTER[2]))
|
||
|
{
|
||
|
throw std::runtime_error("ErrorParameterException: Invalid parameters.");
|
||
|
}
|
||
|
o.m_PX = center.m_X;
|
||
|
o.m_PY = center.m_Y;
|
||
|
o.m_PZ = center.m_Z;
|
||
|
|
||
|
if (std::abs(o.m_OX - o.m_PX) + std::abs(o.m_OY - o.m_PY) + std::abs(o.m_OZ - o.m_PZ) <= 0)
|
||
|
{
|
||
|
throw std::runtime_error("圆心不能重合");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
LineDone(commandLines);
|
||
|
|
||
|
if (commandLines.empty())
|
||
|
{
|
||
|
throw std::runtime_error("Missing command lines.");
|
||
|
}
|
||
|
|
||
|
auto lineParaRO = StringHelper::GetWords(commandLines[0]);
|
||
|
if (lineParaRO[0] != "RH" || lineParaRO.size() != 3)
|
||
|
{
|
||
|
throw std::runtime_error("ErrorParameterException: Missing parameters.");
|
||
|
}
|
||
|
|
||
|
o.m_AR = std::stod(lineParaRO[1]);
|
||
|
o.m_H = std::stod(lineParaRO[2]);
|
||
|
|
||
|
if (o.m_AR < 0 || o.m_H <= 0)
|
||
|
{
|
||
|
throw std::runtime_error("Radius must be >= 0 and height > 0.");
|
||
|
}
|
||
|
|
||
|
LineDone(commandLines);
|
||
|
}
|
||
|
|
||
|
void SolidInterpreter::ROTATIONSOLID(std::vector<std::string> &commandLines, Solid_M &o)
|
||
|
{
|
||
|
if (commandLines.empty())
|
||
|
{
|
||
|
throw std::runtime_error("Missing command lines.");
|
||
|
}
|
||
|
|
||
|
auto lineParaAXIS = StringHelper::GetWords(commandLines[0]);
|
||
|
if (lineParaAXIS[0] != "AXIS" || lineParaAXIS.size() != 3)
|
||
|
{
|
||
|
throw std::runtime_error("ErrorParameterException: Missing parameters.");
|
||
|
}
|
||
|
|
||
|
Point3D_M p1, p2;
|
||
|
if (!ParsePointLoc(p1, lineParaAXIS[1]) || !ParsePointLoc(p2, lineParaAXIS[2]))
|
||
|
{
|
||
|
throw std::runtime_error("ErrorParameterException: Invalid parameters.");
|
||
|
}
|
||
|
|
||
|
o.m_OX = p1.m_X;
|
||
|
o.m_OY = p1.m_Y;
|
||
|
o.m_OZ = p1.m_Z;
|
||
|
o.m_PX = p2.m_X;
|
||
|
o.m_PY = p2.m_Y;
|
||
|
o.m_PZ = p2.m_Z;
|
||
|
|
||
|
LineDone(commandLines);
|
||
|
|
||
|
if (commandLines.empty())
|
||
|
{
|
||
|
throw std::runtime_error("Missing command lines.");
|
||
|
}
|
||
|
|
||
|
auto lineParaBASE = StringHelper::GetWords(commandLines[0]);
|
||
|
if (lineParaBASE[0] != "BASE" || lineParaBASE.size() != 2)
|
||
|
{
|
||
|
throw std::runtime_error("ErrorParameterException: Missing parameters.");
|
||
|
}
|
||
|
|
||
|
int baseId = DataManager::GetObjectIDByName(lineParaBASE[1]);
|
||
|
if (baseId == -1)
|
||
|
{
|
||
|
throw std::runtime_error("ObjectNotFoundException: " + lineParaBASE[1]);
|
||
|
}
|
||
|
int srcType = DataManager::GetObjectByID(baseId)->GetType();
|
||
|
if ((srcType == 3) || (srcType == 4) || (srcType == 5))
|
||
|
{
|
||
|
throw std::runtime_error("旋转体不支持以球面、管道面、旋转为基面。");
|
||
|
}
|
||
|
o.m_Src[0] = baseId;
|
||
|
|
||
|
LineDone(commandLines);
|
||
|
|
||
|
o.m_AR = 360;
|
||
|
if (!commandLines.empty())
|
||
|
{
|
||
|
auto lineParaANGLE = StringHelper::GetWords(commandLines[0]);
|
||
|
if (lineParaANGLE[0] == "ANGLE")
|
||
|
{
|
||
|
if (lineParaANGLE.size() != 2)
|
||
|
{
|
||
|
throw std::runtime_error("ErrorParameterException: Missing parameters.");
|
||
|
}
|
||
|
|
||
|
o.m_AR= std::stod(lineParaANGLE[1]);
|
||
|
if (o.m_AR <= 0 || o.m_AR > 360)
|
||
|
{
|
||
|
throw std::runtime_error("旋转角度(ANGLE)范围应为(0,360].");
|
||
|
}
|
||
|
|
||
|
LineDone(commandLines);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void SolidInterpreter::SWEEPSOLID(std::vector<std::string> &commandLines, Solid_M &o)
|
||
|
{
|
||
|
if (commandLines.empty())
|
||
|
{
|
||
|
throw std::runtime_error("Missing command lines.");
|
||
|
}
|
||
|
|
||
|
auto lineParaBASE = StringHelper::GetWords(commandLines[0]);
|
||
|
if (lineParaBASE[0] != "BASE" || lineParaBASE.size() != 2)
|
||
|
{
|
||
|
throw std::runtime_error("ErrorParameterException: Missing parameters.");
|
||
|
}
|
||
|
|
||
|
int baseId = DataManager::GetObjectIDByName(lineParaBASE[1]);
|
||
|
if (baseId == -1)
|
||
|
{
|
||
|
throw std::runtime_error("ObjectNotFoundException: " + lineParaBASE[1]);
|
||
|
}
|
||
|
|
||
|
o.m_Src[0] = baseId;
|
||
|
|
||
|
LineDone(commandLines);
|
||
|
|
||
|
if (commandLines.empty())
|
||
|
{
|
||
|
throw std::runtime_error("Missing command lines.");
|
||
|
}
|
||
|
|
||
|
auto lineParaGENERATE = StringHelper::GetWords(commandLines[0]);
|
||
|
if (lineParaGENERATE[0] != "GENERATE" || lineParaGENERATE.size() != 2)
|
||
|
{
|
||
|
throw std::runtime_error("ErrorParameterException: Missing parameters.");
|
||
|
}
|
||
|
|
||
|
int generateId = DataManager::GetObjectIDByName(lineParaGENERATE[1]);
|
||
|
|
||
|
if (generateId == -1)
|
||
|
{
|
||
|
throw std::runtime_error("ObjectNotFoundException: " + lineParaGENERATE[1]);
|
||
|
}
|
||
|
|
||
|
o.m_Src[1] = generateId;
|
||
|
|
||
|
LineDone(commandLines);
|
||
|
}
|
||
|
|
||
|
void SolidInterpreter::SOLID(std::vector<std::string> &commandLines, Solid_M &o)
|
||
|
{
|
||
|
if (commandLines.empty())
|
||
|
{
|
||
|
throw std::runtime_error("Missing command lines.");
|
||
|
}
|
||
|
|
||
|
auto lineParaTHR = StringHelper::GetWords(commandLines[0]);
|
||
|
if (lineParaTHR.size() < 2)
|
||
|
{
|
||
|
throw std::runtime_error("ErrorParameterException: Missing parameters.");
|
||
|
}
|
||
|
|
||
|
std::string geomType = StringHelper::toUpper(lineParaTHR[0]);
|
||
|
if (geomType == "THR")
|
||
|
{
|
||
|
for (size_t i = 1; i < lineParaTHR.size(); ++i)
|
||
|
{
|
||
|
int surfaceId = DataManager::GetObjectIDByName(lineParaTHR[i]);
|
||
|
if (surfaceId == -1)
|
||
|
{
|
||
|
throw std::runtime_error("ObjectNotFoundException: " + lineParaTHR[i]);
|
||
|
}
|
||
|
o.m_Src[i - 1] = surfaceId;
|
||
|
}
|
||
|
}
|
||
|
else if (geomType == "BOOL")
|
||
|
{
|
||
|
o.m_Type = 7;
|
||
|
for (size_t i = 1; i < lineParaTHR.size(); ++i)
|
||
|
{
|
||
|
std::string solidName = lineParaTHR[i];
|
||
|
int boolMode = ParseBoolSymbolFromName(solidName);
|
||
|
int solidId = DataManager::GetObjectIDByName(solidName);
|
||
|
if (solidId == -1)
|
||
|
{
|
||
|
throw std::runtime_error("ObjectNotFoundException: " + solidName);
|
||
|
}
|
||
|
o.m_Src[i - 1] = solidId;
|
||
|
o.m_BoolMode[i - 1] = boolMode;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
throw std::runtime_error("ErrorParameterException: Invalid parameters.");
|
||
|
}
|
||
|
|
||
|
LineDone(commandLines);
|
||
|
}
|