/* SPDX-FileCopyrightText: Copyright (c) 2016 - 2026, the adamantine authors. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception */ #ifndef SCAN_PATH_HH #define SCAN_PATH_HH #include #include #include #include #include #include #include #include namespace adamantine { /** * This enum distinguishes between the two types of scan path segments. */ enum class ScanPathSegmentType { line, point }; /** * This structure stores the relevant information for a single segment. The scan * path input file distingishes between spots and lines, but when we know the * end time and end location, spots become lines with a start point equal to its * end point. Everything one needs can be determined from these three quantities * (and the segment info from the preceding segment) but in the future it might * be worth adding in some redundant information like start time/point and * velocity. */ struct ScanPathSegment { double end_time = std::numeric_limits::signaling_NaN(); // Unit: seconds double power_modifier = std::numeric_limits::signaling_NaN(); // Dimensionless dealii::Point<3> end_point; // Unit: m Quaternion end_rotation; }; /** * Forward declaration of the tester friend class to ScanPath. */ class ScanPathTester; /** * This class calculates the position of the center of a heat source. It also * gives the power modifier for the current segment. It reads in the scan path * from a text file. */ class ScanPath { friend class ScanPathTester; public: /** * Default constructor. This creates an empty scan path with no segment. */ ScanPath() = default; /** * Construtor. * \param[in] scan_path_file is the name of the text file containing the scan * path * \param[in] file_format is the format of the scan path file * \param[in] units_optional_database is the units property tree */ ScanPath(std::string const &scan_path_file, std::string const &file_format, boost::optional const &units_optional_database); /** * Calculate the location of the scan path at a given time for a single * coordinate. */ dealii::Point<3> value(double const time, bool const save_time = true) const; /** * Return the power coefficient for the current segment */ double get_power_modifier(double const time) const; /** * Return the quaternion at the given @p time. The quaternion is interpolated * linearly (Slerp) between the start and the end of the segment. */ Quaternion get_quaternion(double const time) const; /** * Return the scan path's list of segments */ std::vector get_segment_list() const; /** * Read the scan path file and update the list of segments. */ void read_file(); /** * Return true if we reach the end of the scan path. */ bool is_finished() const; /** * Return true if the scan path includes valid rotations/quaternions. */ bool is_five_axis() const; private: /** * Method to load a "segment" scan path file */ void load_segment_scan_path(); /** * Method to load an "event series" scan path file */ void load_event_series_scan_path(); /** * Method to determine the current segment, its start point, and start time. */ void update_current_segment_info(double time, bool save_segment, unsigned int ¤t_segment, dealii::Point<3> &segment_start_point, double &segment_start_time, Quaternion &segment_start_rotation) const; /** * Flag is true if we have reached the end of _scan_path_file. */ bool _scan_path_end = false; /** * Flag is true if quaternions were provided in _scan_path_file. */ bool _five_axis = false; /** * Scaling factor for the distance. */ double _distance_scaling = 1.; /** * Scaling factor for the velocity. */ double _velocity_scaling = 1.; /** * File name of the scan path */ std::string _scan_path_file; /** * Format of the scan path file, either segment of event_series. */ std::string _file_format; /** * Time the last time _scan_path_file was updated. */ std::filesystem::file_time_type _last_write_time; /** * The list of information about each segment in the scan path. */ std::vector _segment_list; /** * The index of the old segment in the scan path. */ mutable unsigned int _old_segment = 0; }; } // namespace adamantine #endif