// OPERATION.h #ifndef OPERATION_H #define OPERATION_H #include #include #include #include using json = nlohmann::json; // 毫米转米函数 inline double MMToM(double MM) { return std::round(MM / 1000.0 * 100000.0) / 100000.0; // 保留5位小数 } // 帧内容类 class C_ObjStates { public: std::string i = ""; // 模型代码 std::string tx = ""; // tx std::string ty = ""; // ty std::string tz = ""; // tz std::string qx = ""; // qx std::string qy = ""; // qy std::string qz = ""; // qz std::string qw = ""; // qw }; NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(C_ObjStates, i, tx, ty, tz, qx, qy, qz, qw) // 工艺类 class C_Craft { public: std::string CraftCode; std::string CraftValue; }; NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(C_Craft, CraftCode, CraftValue) // 帧信号类 class C_Signalwrite { public: std::string TagID; std::string TagValue; }; NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(C_Signalwrite, TagID, TagValue) // 可见性类 class C_Visible { public: std::string ModelCode; std::string Visible; }; NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(C_Visible, ModelCode, Visible) // 旋转类 class C_Rotation { public: std::string ModelCode; std::string Axis; int Rate = 0; }; NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(C_Rotation, ModelCode, Axis, Rate) // 等待类 class C_Wait { public: std::string WaitStr; }; NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(C_Wait, WaitStr) // 附加类 class C_Attach { public: std::string AttachToModelCode = ""; std::string AttachToModelName = ""; bool IsTwoWay = false; bool IsAttach = false; }; NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(C_Attach, AttachToModelCode, AttachToModelName, IsTwoWay, IsAttach) // 帧类 class C_Frames { public: std::string time = "0.01"; // 帧时间 std::vector objStates; std::vector crafts; std::vector signalwrites; std::vector visibles; std::vector rotations; std::vector waits; std::vector attachs; }; NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(C_Frames, time, objStates, crafts, signalwrites, visibles, rotations, waits, attachs) // 操作类(帧集合) class C_OPERATION { public: std::vector frames; }; NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(C_OPERATION, frames) // 项目操作类 class P_OPERATION { public: C_OPERATION OPERATION; }; NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(P_OPERATION, OPERATION) // 功能类 class P_OPERATION_Func { public: /** * 生成线框播放数据 * @param PP_FrameValue 帧率值 * @param modelCode 模型代码 * @param ptQList 点位置和四元数列表 [x, y, z, qx, qy, qz, qw] * @return 帧列表 */ static std::vector _MakeCraftPlayData_Line_Frame( int PP_FrameValue, const std::string &modelCode, const std::vector> &ptQList) { std::vector frames; for (size_t i = 0; i < ptQList.size(); i++) { const auto &currQ = ptQList[i]; if (currQ.size() < 7) { // 数据不足,跳过 continue; } // 创建对象状态 C_ObjStates objState; objState.i = modelCode; objState.tx = std::to_string(MMToM(currQ[0])); objState.ty = std::to_string(MMToM(currQ[1])); objState.tz = std::to_string(MMToM(currQ[2])); objState.qx = std::to_string(currQ[3]); objState.qy = std::to_string(currQ[4]); objState.qz = std::to_string(currQ[5]); objState.qw = std::to_string(currQ[6]); // 创建帧 C_Frames frame; frame.time = std::to_string(PP_FrameValue * i / 1000.0); frame.objStates.push_back(objState); frames.push_back(frame); } return frames; } /** * 生成线框播放数据(简化版本) * @param frameRate 帧率 * @param modelCode 模型代码 * @param positions 位置数组 [x, y, z] (毫米) * @param quaternions 四元数数组 [qx, qy, qz, qw] * @return 帧列表 */ static std::vector MakeCraftPlayData_Simple( int frameRate, const std::string &modelCode, const std::vector> &positions, const std::vector> &quaternions) { if (positions.size() != quaternions.size()) { // 数据长度不匹配,返回空列表 return {}; } std::vector frames; for (size_t i = 0; i < positions.size(); i++) { if (positions[i].size() < 3 || quaternions[i].size() < 4) { continue; } // 创建对象状态 C_ObjStates objState; objState.i = modelCode; objState.tx = std::to_string(MMToM(positions[i][0])); objState.ty = std::to_string(MMToM(positions[i][1])); objState.tz = std::to_string(MMToM(positions[i][2])); objState.qx = std::to_string(quaternions[i][0]); objState.qy = std::to_string(quaternions[i][1]); objState.qz = std::to_string(quaternions[i][2]); objState.qw = std::to_string(quaternions[i][3]); // 创建帧 C_Frames frame; frame.time = std::to_string(i / static_cast(frameRate)); frame.objStates.push_back(objState); frames.push_back(frame); } return frames; } /** * 生成完整的操作对象 * @param frameRate 帧率 * @param modelCode 模型代码 * @param positions 位置数组 * @param quaternions 四元数数组 * @return P_OPERATION对象 */ static P_OPERATION MakeOperation( int frameRate, const std::string &modelCode, const std::vector> &positions, const std::vector> &quaternions) { auto frames = MakeCraftPlayData_Simple(frameRate, modelCode, positions, quaternions); P_OPERATION operation; operation.OPERATION.frames = frames; return operation; } /** * 添加信号写入到帧 * @param frame 目标帧 * @param tagID 标签ID * @param tagValue 标签值 */ static void AddSignalWrite(C_Frames &frame, const std::string &tagID, const std::string &tagValue) { C_Signalwrite signal; signal.TagID = tagID; signal.TagValue = tagValue; frame.signalwrites.push_back(signal); } /** * 添加工艺命令到帧 * @param frame 目标帧 * @param craftCode 工艺代码 * @param craftValue 工艺值 */ static void AddCraft(C_Frames &frame, const std::string &craftCode, const std::string &craftValue) { C_Craft craft; craft.CraftCode = craftCode; craft.CraftValue = craftValue; frame.crafts.push_back(craft); } /** * 添加可见性控制到帧 * @param frame 目标帧 * @param modelCode 模型代码 * @param visible 是否可见 ("true" 或 "false") */ static void AddVisible(C_Frames &frame, const std::string &modelCode, const std::string &visible) { C_Visible visibleCmd; visibleCmd.ModelCode = modelCode; visibleCmd.Visible = visible; frame.visibles.push_back(visibleCmd); } /** * 添加旋转控制到帧 * @param frame 目标帧 * @param modelCode 模型代码 * @param axis 旋转轴 ("x", "y", "z") * @param rate 旋转速率 */ static void AddRotation(C_Frames &frame, const std::string &modelCode, const std::string &axis, int rate) { C_Rotation rotation; rotation.ModelCode = modelCode; rotation.Axis = axis; rotation.Rate = rate; frame.rotations.push_back(rotation); } /** * 添加等待命令到帧 * @param frame 目标帧 * @param waitStr 等待字符串 */ static void AddWait(C_Frames &frame, const std::string &waitStr) { C_Wait wait; wait.WaitStr = waitStr; frame.waits.push_back(wait); } /** * 添加附加命令到帧 * @param frame 目标帧 * @param attachToModelCode 附加目标模型代码 * @param attachToModelName 附加目标模型名称 * @param isTwoWay 是否双向附加 * @param isAttach 是否附加(true=附加,false=分离) */ static void AddAttach(C_Frames &frame, const std::string &attachToModelCode, const std::string &attachToModelName, bool isTwoWay, bool isAttach) { C_Attach attach; attach.AttachToModelCode = attachToModelCode; attach.AttachToModelName = attachToModelName; attach.IsTwoWay = isTwoWay; attach.IsAttach = isAttach; frame.attachs.push_back(attach); } }; #endif // OPERATION_H