mirror of
https://github.com/subsurface/subsurface.git
synced 2025-01-31 22:43:25 +00:00
profile: C++-ify plot_info
Use more C++ style memory management for plot_info: Use std::vector for array data. Return the plot_info instead of filling an output parameter. Add a constructor/destructor pair so that the caller isn't bothered with memory management. The bulk of the commit is replacement of pointers with references, which is kind of gratuitous. But I started and then went on... Default initializiation of gas_pressures made it necessary to convert gas.c to c++, though with minimal changes to the code. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
24a6af9ac1
commit
9f4a72a692
14 changed files with 635 additions and 670 deletions
|
@ -88,7 +88,7 @@ SOURCES += subsurface-mobile-main.cpp \
|
|||
core/deco.cpp \
|
||||
core/divesite.cpp \
|
||||
core/equipment.c \
|
||||
core/gas.c \
|
||||
core/gas.cpp \
|
||||
core/membuffer.cpp \
|
||||
core/selection.cpp \
|
||||
core/sha1.cpp \
|
||||
|
|
|
@ -99,7 +99,7 @@ set(SUBSURFACE_CORE_LIB_SRCS
|
|||
format.h
|
||||
fulltext.cpp
|
||||
fulltext.h
|
||||
gas.c
|
||||
gas.cpp
|
||||
gas.h
|
||||
gas-model.cpp
|
||||
gaspressures.cpp
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "gettext.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <QtGlobal> // for QT_TRANSLATE_NOOP
|
||||
|
||||
/* Perform isobaric counterdiffusion calculations for gas changes in trimix dives.
|
||||
* Here we use the rule-of-fifths where, during a change involving trimix gas, the increase in nitrogen
|
|
@ -60,9 +60,11 @@ static inline int get_n2(struct gasmix mix)
|
|||
|
||||
int pscr_o2(const double amb_pressure, struct gasmix mix);
|
||||
|
||||
#ifdef __cplusplus
|
||||
struct gas_pressures {
|
||||
double o2, n2, he;
|
||||
double o2 = 0.0, n2 = 0.0, he = 0.0;
|
||||
};
|
||||
#endif
|
||||
|
||||
extern void sanitize_gasmix(struct gasmix *mix);
|
||||
extern int gasmix_distance(struct gasmix a, struct gasmix b);
|
||||
|
|
|
@ -86,8 +86,6 @@ static void dump_pr_track(int cyl, std::vector<pr_track_t> &track_pr)
|
|||
*/
|
||||
static void fill_missing_segment_pressures(std::vector<pr_track_t> &list, enum interpolation_strategy strategy)
|
||||
{
|
||||
double magic;
|
||||
|
||||
for (auto it = list.begin(); it != list.end(); ++it) {
|
||||
int start = it->start, end;
|
||||
int pt_sum = 0, pt = 0;
|
||||
|
@ -134,7 +132,7 @@ static void fill_missing_segment_pressures(std::vector<pr_track_t> &list, enum i
|
|||
break;
|
||||
case TIME:
|
||||
if (it->t_end && (tmp->t_start - tmp->t_end)) {
|
||||
magic = (it->t_start - tmp->t_end) / (tmp->t_start - tmp->t_end);
|
||||
double magic = (it->t_start - tmp->t_end) / (tmp->t_start - tmp->t_end);
|
||||
it->end = lrint(start - (start - end) * magic);
|
||||
} else {
|
||||
it->end = start;
|
||||
|
@ -155,35 +153,33 @@ void dump_pr_interpolate(int i, pr_interpolate_t interpolate_pr)
|
|||
#endif
|
||||
|
||||
|
||||
static pr_interpolate_t get_pr_interpolate_data(const pr_track_t &segment, struct plot_info *pi, int cur)
|
||||
{ // cur = index to pi->entry corresponding to t_end of segment;
|
||||
static pr_interpolate_t get_pr_interpolate_data(const pr_track_t &segment, struct plot_info &pi, int cur)
|
||||
{ // cur = index to pi.entry corresponding to t_end of segment;
|
||||
pr_interpolate_t interpolate;
|
||||
int i;
|
||||
struct plot_data *entry;
|
||||
|
||||
interpolate.start = segment.start;
|
||||
interpolate.end = segment.end;
|
||||
interpolate.acc_pressure_time = 0;
|
||||
interpolate.pressure_time = 0;
|
||||
|
||||
for (i = 0; i < pi->nr; i++) {
|
||||
entry = pi->entry + i;
|
||||
for (i = 0; i < pi.nr; i++) {
|
||||
const plot_data &entry = pi.entry[i];
|
||||
|
||||
if (entry->sec < segment.t_start)
|
||||
if (entry.sec < segment.t_start)
|
||||
continue;
|
||||
interpolate.pressure_time += entry->pressure_time;
|
||||
if (entry->sec >= segment.t_end)
|
||||
interpolate.pressure_time += entry.pressure_time;
|
||||
if (entry.sec >= segment.t_end)
|
||||
break;
|
||||
if (i <= cur)
|
||||
interpolate.acc_pressure_time += entry->pressure_time;
|
||||
interpolate.acc_pressure_time += entry.pressure_time;
|
||||
}
|
||||
return interpolate;
|
||||
}
|
||||
|
||||
static void fill_missing_tank_pressures(const struct dive *dive, struct plot_info *pi, std::vector<pr_track_t> &track_pr, int cyl)
|
||||
static void fill_missing_tank_pressures(const struct dive *dive, struct plot_info &pi, std::vector<pr_track_t> &track_pr, int cyl)
|
||||
{
|
||||
int i;
|
||||
struct plot_data *entry;
|
||||
pr_interpolate_t interpolate = { 0, 0, 0, 0 };
|
||||
int cur_pr;
|
||||
enum interpolation_strategy strategy;
|
||||
|
@ -214,13 +210,10 @@ static void fill_missing_tank_pressures(const struct dive *dive, struct plot_inf
|
|||
* The first two pi structures are "fillers", but in case we don't have a sample
|
||||
* at time 0 we need to process the second of them here, therefore i=1 */
|
||||
auto last_segment = track_pr.end();
|
||||
for (i = 1; i < pi->nr; i++) { // For each point on the profile:
|
||||
double magic;
|
||||
int pressure;
|
||||
for (i = 1; i < pi.nr; i++) { // For each point on the profile:
|
||||
const struct plot_data &entry = pi.entry[i];
|
||||
|
||||
entry = pi->entry + i;
|
||||
|
||||
pressure = get_plot_pressure(pi, i, cyl);
|
||||
int pressure = get_plot_pressure(pi, i, cyl);
|
||||
|
||||
if (pressure) { // If there is a valid pressure value,
|
||||
last_segment = track_pr.end(); // get rid of interpolation data,
|
||||
|
@ -230,15 +223,15 @@ static void fill_missing_tank_pressures(const struct dive *dive, struct plot_inf
|
|||
// If there is NO valid pressure value..
|
||||
// Find the pressure segment corresponding to this entry..
|
||||
auto it = track_pr.begin();
|
||||
while (it != track_pr.end() && it->t_end < entry->sec) // Find the track_pr with end time..
|
||||
++it; // ..that matches the plot_info time (entry->sec)
|
||||
while (it != track_pr.end() && it->t_end < entry.sec) // Find the track_pr with end time..
|
||||
++it; // ..that matches the plot_info time (entry.sec)
|
||||
|
||||
// After last segment? All done.
|
||||
if (it == track_pr.end())
|
||||
break;
|
||||
|
||||
// Before first segment, or between segments.. Go on, no interpolation.
|
||||
if (it->t_start > entry->sec)
|
||||
if (it->t_start > entry.sec)
|
||||
continue;
|
||||
|
||||
if (!it->pressure_time) { // Empty segment?
|
||||
|
@ -249,7 +242,7 @@ static void fill_missing_tank_pressures(const struct dive *dive, struct plot_inf
|
|||
|
||||
// If there is a valid segment but no tank pressure ..
|
||||
if (it == last_segment) {
|
||||
interpolate.acc_pressure_time += entry->pressure_time;
|
||||
interpolate.acc_pressure_time += entry.pressure_time;
|
||||
} else {
|
||||
// Set up an interpolation structure
|
||||
interpolate = get_pr_interpolate_data(*it, pi, i);
|
||||
|
@ -261,14 +254,14 @@ static void fill_missing_tank_pressures(const struct dive *dive, struct plot_inf
|
|||
/* if this segment has pressure_time, then calculate a new interpolated pressure */
|
||||
if (interpolate.pressure_time) {
|
||||
/* Overall pressure change over total pressure-time for this segment*/
|
||||
magic = (interpolate.end - interpolate.start) / (double)interpolate.pressure_time;
|
||||
double magic = (interpolate.end - interpolate.start) / (double)interpolate.pressure_time;
|
||||
|
||||
/* Use that overall pressure change to update the current pressure */
|
||||
cur_pr = lrint(interpolate.start + magic * interpolate.acc_pressure_time);
|
||||
}
|
||||
} else {
|
||||
magic = (interpolate.end - interpolate.start) / (it->t_end - it->t_start);
|
||||
cur_pr = lrint(it->start + magic * (entry->sec - it->t_start));
|
||||
double magic = (interpolate.end - interpolate.start) / (it->t_end - it->t_start);
|
||||
cur_pr = lrint(it->start + magic * (entry.sec - it->t_start));
|
||||
}
|
||||
set_plot_pressure_data(pi, i, INTERPOLATED_PR, cyl, cur_pr); // and store the interpolated data in plot_info
|
||||
}
|
||||
|
@ -285,10 +278,10 @@ static void fill_missing_tank_pressures(const struct dive *dive, struct plot_inf
|
|||
* scale pressures, so it ends up being a unitless scaling
|
||||
* factor.
|
||||
*/
|
||||
static inline int calc_pressure_time(const struct dive *dive, struct plot_data *a, struct plot_data *b)
|
||||
static inline int calc_pressure_time(const struct dive *dive, const struct plot_data &a, const struct plot_data &b)
|
||||
{
|
||||
int time = b->sec - a->sec;
|
||||
int depth = (a->depth + b->depth) / 2;
|
||||
int time = b.sec - a.sec;
|
||||
int depth = (a.depth + b.depth) / 2;
|
||||
|
||||
if (depth <= SURFACE_THRESHOLD)
|
||||
return 0;
|
||||
|
@ -298,10 +291,10 @@ static inline int calc_pressure_time(const struct dive *dive, struct plot_data *
|
|||
|
||||
#ifdef PRINT_PRESSURES_DEBUG
|
||||
// A CCR debugging tool that prints the gas pressures in cylinder 0 and in the diluent cylinder, used in populate_pressure_information():
|
||||
static void debug_print_pressures(struct plot_info *pi)
|
||||
static void debug_print_pressures(struct plot_info &pi)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < pi->nr; i++)
|
||||
for (i = 0; i < pi.nr; i++)
|
||||
printf("%5d |%9d | %9d |\n", i, get_plot_sensor_pressure(pi, i), get_plot_interpolated_pressure(pi, i));
|
||||
}
|
||||
#endif
|
||||
|
@ -315,8 +308,7 @@ static void debug_print_pressures(struct plot_info *pi)
|
|||
* calculates the summed pressure-time value for the duration of the dive and stores these in the pr_track_t
|
||||
* structures. This function is called by create_plot_info_new() in profile.cpp
|
||||
*/
|
||||
extern "C"
|
||||
void populate_pressure_information(const struct dive *dive, const struct divecomputer *dc, struct plot_info *pi, int sensor)
|
||||
void populate_pressure_information(const struct dive *dive, const struct divecomputer *dc, struct plot_info &pi, int sensor)
|
||||
{
|
||||
int first, last, cyl;
|
||||
cylinder_t *cylinder = get_cylinder(dive, sensor);
|
||||
|
@ -337,7 +329,7 @@ void populate_pressure_information(const struct dive *dive, const struct divecom
|
|||
|
||||
/* Get a rough range of where we have any pressures at all */
|
||||
first = last = -1;
|
||||
for (int i = 0; i < pi->nr; i++) {
|
||||
for (int i = 0; i < pi.nr; i++) {
|
||||
int pressure = get_plot_sensor_pressure(pi, i, sensor);
|
||||
|
||||
if (!pressure)
|
||||
|
@ -366,9 +358,9 @@ void populate_pressure_information(const struct dive *dive, const struct divecom
|
|||
b_ev = get_next_event(dc->events, "modechange");
|
||||
|
||||
for (int i = first; i <= last; i++) {
|
||||
struct plot_data *entry = pi->entry + i;
|
||||
struct plot_data &entry = pi.entry[i];
|
||||
int pressure = get_plot_sensor_pressure(pi, i, sensor);
|
||||
int time = entry->sec;
|
||||
int time = entry.sec;
|
||||
|
||||
while (ev && ev->time.seconds <= time) { // Find 1st gaschange event after
|
||||
cyl = get_cylinder_index(dive, ev); // the current gas change.
|
||||
|
@ -383,9 +375,9 @@ void populate_pressure_information(const struct dive *dive, const struct divecom
|
|||
}
|
||||
|
||||
if (current != std::string::npos) { // calculate pressure-time, taking into account the dive mode for this specific segment.
|
||||
entry->pressure_time = (int)(calc_pressure_time(dive, entry - 1, entry) * gasfactor[dmode] + 0.5);
|
||||
track[current].pressure_time += entry->pressure_time;
|
||||
track[current].t_end = entry->sec;
|
||||
entry.pressure_time = (int)(calc_pressure_time(dive, pi.entry[i - 1], entry) * gasfactor[dmode] + 0.5);
|
||||
track[current].pressure_time += entry.pressure_time;
|
||||
track[current].t_end = entry.sec;
|
||||
if (pressure)
|
||||
track[current].end = pressure;
|
||||
}
|
||||
|
@ -422,7 +414,7 @@ void populate_pressure_information(const struct dive *dive, const struct divecom
|
|||
// missing entries that need to be interpolated.
|
||||
// Or maybe we didn't have a previous one at all,
|
||||
// and this is the first pressure entry.
|
||||
track.emplace_back(pressure, entry->sec);
|
||||
track.emplace_back(pressure, entry.sec);
|
||||
current = track.size() - 1;
|
||||
dense = 1;
|
||||
}
|
||||
|
|
|
@ -3,12 +3,8 @@
|
|||
#define GASPRESSURES_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void populate_pressure_information(const struct dive *, const struct divecomputer *, struct plot_info *, int);
|
||||
void populate_pressure_information(const struct dive *, const struct divecomputer *, struct plot_info &, int);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // GASPRESSURES_H
|
||||
|
|
865
core/profile.cpp
865
core/profile.cpp
File diff suppressed because it is too large
Load diff
153
core/profile.h
153
core/profile.h
|
@ -2,20 +2,22 @@
|
|||
#ifndef PROFILE_H
|
||||
#define PROFILE_H
|
||||
|
||||
#include "dive.h"
|
||||
#include "sample.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
#include "gas.h" // gas_pressures
|
||||
#include "sample.h" // MAX_O2_SENSORS
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
enum velocity_t {
|
||||
STABLE,
|
||||
SLOW,
|
||||
MODERATE,
|
||||
FAST,
|
||||
CRAZY
|
||||
} velocity_t;
|
||||
};
|
||||
|
||||
enum plot_pressure {
|
||||
SENSOR_PR = 0,
|
||||
|
@ -25,6 +27,7 @@ enum plot_pressure {
|
|||
|
||||
struct membuffer;
|
||||
struct deco_state;
|
||||
struct dive;
|
||||
struct divecomputer;
|
||||
|
||||
/*
|
||||
|
@ -35,72 +38,74 @@ struct plot_pressure_data {
|
|||
};
|
||||
|
||||
struct plot_data {
|
||||
unsigned int in_deco : 1;
|
||||
int sec;
|
||||
int temperature;
|
||||
bool in_deco = false;
|
||||
int sec = 0;
|
||||
int temperature = 0;
|
||||
/* Depth info */
|
||||
int depth;
|
||||
int ceiling;
|
||||
int ceilings[16];
|
||||
int percentages[16];
|
||||
int ndl;
|
||||
int tts;
|
||||
int rbt;
|
||||
int stoptime;
|
||||
int stopdepth;
|
||||
int cns;
|
||||
int smoothed;
|
||||
int sac;
|
||||
int running_sum;
|
||||
int depth = 0;
|
||||
int ceiling = 0;
|
||||
int ceilings[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
int percentages[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
int ndl = 0;
|
||||
int tts = 0;
|
||||
int rbt = 0;
|
||||
int stoptime = 0;
|
||||
int stopdepth = 0;
|
||||
int cns = 0;
|
||||
int smoothed = 0;
|
||||
int sac = 0;
|
||||
int running_sum = 0;
|
||||
struct gas_pressures pressures;
|
||||
pressure_t o2pressure; // for rebreathers, this is consensus measured po2, or setpoint otherwise. 0 for OC.
|
||||
pressure_t o2sensor[MAX_O2_SENSORS]; //for rebreathers with several sensors
|
||||
pressure_t o2setpoint;
|
||||
pressure_t scr_OC_pO2;
|
||||
int mod, ead, end, eadd;
|
||||
velocity_t velocity;
|
||||
int speed;
|
||||
// TODO: make pressure_t default to 0
|
||||
pressure_t o2pressure = { 0 }; // for rebreathers, this is consensus measured po2, or setpoint otherwise. 0 for OC.
|
||||
pressure_t o2sensor[MAX_O2_SENSORS] = {{ 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }}; //for rebreathers with several sensors
|
||||
pressure_t o2setpoint = { 0 };
|
||||
pressure_t scr_OC_pO2 = { 0 };
|
||||
int mod = 0, ead = 0, end = 0, eadd = 0;
|
||||
velocity_t velocity = STABLE;
|
||||
int speed = 0;
|
||||
/* values calculated by us */
|
||||
unsigned int in_deco_calc : 1;
|
||||
int ndl_calc;
|
||||
int tts_calc;
|
||||
int stoptime_calc;
|
||||
int stopdepth_calc;
|
||||
int pressure_time;
|
||||
int heartbeat;
|
||||
int bearing;
|
||||
double ambpressure;
|
||||
double gfline;
|
||||
double surface_gf;
|
||||
double current_gf;
|
||||
double density;
|
||||
bool icd_warning;
|
||||
bool in_deco_calc = false;
|
||||
int ndl_calc = 0;
|
||||
int tts_calc = 0;
|
||||
int stoptime_calc = 0;
|
||||
int stopdepth_calc = 0;
|
||||
int pressure_time = 0;
|
||||
int heartbeat = 0;
|
||||
int bearing = 0;
|
||||
double ambpressure = 0.0;
|
||||
double gfline = 0.0;
|
||||
double surface_gf = 0.0;
|
||||
double current_gf = 0.0;
|
||||
double density = 0.0;
|
||||
bool icd_warning = false;
|
||||
};
|
||||
|
||||
/* Plot info with smoothing, velocity indication
|
||||
* and one-, two- and three-minute minimums and maximums */
|
||||
struct plot_info {
|
||||
int nr;
|
||||
int nr_cylinders;
|
||||
int maxtime;
|
||||
int meandepth, maxdepth;
|
||||
int minpressure, maxpressure;
|
||||
int minhr, maxhr;
|
||||
int mintemp, maxtemp;
|
||||
enum {AIR, NITROX, TRIMIX, FREEDIVING} dive_type;
|
||||
double endtempcoord;
|
||||
double maxpp;
|
||||
bool waypoint_above_ceiling;
|
||||
struct plot_data *entry;
|
||||
struct plot_pressure_data *pressures; /* cylinders.nr blocks of nr entries. */
|
||||
int nr = 0; // TODO: remove - redundant with entry.size()
|
||||
int nr_cylinders = 0;
|
||||
int maxtime = 0;
|
||||
int meandepth = 0, maxdepth = 0;
|
||||
int minpressure = 0, maxpressure = 0;
|
||||
int minhr = 0, maxhr = 0;
|
||||
int mintemp = 0, maxtemp = 0;
|
||||
enum {AIR, NITROX, TRIMIX, FREEDIVING} dive_type = AIR;
|
||||
double endtempcoord = 0.0;
|
||||
double maxpp = 0.0;
|
||||
bool waypoint_above_ceiling = false;
|
||||
std::vector<plot_data> entry;
|
||||
std::vector<plot_pressure_data> pressures; /* cylinders.nr blocks of nr entries. */
|
||||
|
||||
plot_info();
|
||||
~plot_info();
|
||||
};
|
||||
|
||||
#define AMB_PERCENTAGE 50.0
|
||||
|
||||
extern void init_plot_info(struct plot_info *pi);
|
||||
/* when planner_dc is non-null, this is called in planner mode. */
|
||||
extern void create_plot_info_new(const struct dive *dive, const struct divecomputer *dc, struct plot_info *pi, const struct deco_state *planner_ds);
|
||||
extern void free_plot_info_data(struct plot_info *pi);
|
||||
extern struct plot_info create_plot_info_new(const struct dive *dive, const struct divecomputer *dc, const struct deco_state *planner_ds);
|
||||
|
||||
/*
|
||||
* When showing dive profiles, we scale things to the
|
||||
|
@ -110,46 +115,40 @@ extern void free_plot_info_data(struct plot_info *pi);
|
|||
* We also need to add 180 seconds at the end so the min/max
|
||||
* plots correctly
|
||||
*/
|
||||
extern int get_maxtime(const struct plot_info *pi);
|
||||
extern int get_maxtime(const struct plot_info &pi);
|
||||
|
||||
/* get the maximum depth to which we want to plot */
|
||||
extern int get_maxdepth(const struct plot_info *pi);
|
||||
extern int get_maxdepth(const struct plot_info &pi);
|
||||
|
||||
static inline int get_plot_pressure_data(const struct plot_info *pi, int idx, enum plot_pressure sensor, int cylinder)
|
||||
static inline int get_plot_pressure_data(const struct plot_info &pi, int idx, enum plot_pressure sensor, int cylinder)
|
||||
{
|
||||
return pi->pressures[cylinder + idx * pi->nr_cylinders].data[sensor];
|
||||
return pi.pressures[cylinder + idx * pi.nr_cylinders].data[sensor];
|
||||
}
|
||||
|
||||
static inline void set_plot_pressure_data(struct plot_info *pi, int idx, enum plot_pressure sensor, int cylinder, int value)
|
||||
static inline void set_plot_pressure_data(struct plot_info &pi, int idx, enum plot_pressure sensor, int cylinder, int value)
|
||||
{
|
||||
pi->pressures[cylinder + idx * pi->nr_cylinders].data[sensor] = value;
|
||||
pi.pressures[cylinder + idx * pi.nr_cylinders].data[sensor] = value;
|
||||
}
|
||||
|
||||
static inline int get_plot_sensor_pressure(const struct plot_info *pi, int idx, int cylinder)
|
||||
static inline int get_plot_sensor_pressure(const struct plot_info &pi, int idx, int cylinder)
|
||||
{
|
||||
return get_plot_pressure_data(pi, idx, SENSOR_PR, cylinder);
|
||||
}
|
||||
|
||||
static inline int get_plot_interpolated_pressure(const struct plot_info *pi, int idx, int cylinder)
|
||||
static inline int get_plot_interpolated_pressure(const struct plot_info &pi, int idx, int cylinder)
|
||||
{
|
||||
return get_plot_pressure_data(pi, idx, INTERPOLATED_PR, cylinder);
|
||||
}
|
||||
|
||||
static inline int get_plot_pressure(const struct plot_info *pi, int idx, int cylinder)
|
||||
static inline int get_plot_pressure(const struct plot_info &pi, int idx, int cylinder)
|
||||
{
|
||||
int res = get_plot_sensor_pressure(pi, idx, cylinder);
|
||||
return res ? res : get_plot_interpolated_pressure(pi, idx, cylinder);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
// C++ only formatting functions
|
||||
#include <string>
|
||||
#include <vector>
|
||||
// Returns index of sample and array of strings describing the dive details at given time
|
||||
std::pair<int, std::vector<std::string>> get_plot_details_new(const struct dive *d, const struct plot_info *pi, int time);
|
||||
std::vector<std::string> compare_samples(const struct dive *d, const struct plot_info *pi, int idx1, int idx2, bool sum);
|
||||
std::pair<int, std::vector<std::string>> get_plot_details_new(const struct dive *d, const struct plot_info &pi, int time);
|
||||
std::vector<std::string> compare_samples(const struct dive *d, const struct plot_info &pi, int idx1, int idx2, bool sum);
|
||||
|
||||
#endif
|
||||
#endif // PROFILE_H
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
#include "core/save-profiledata.h"
|
||||
#include "core/dive.h"
|
||||
#include "core/profile.h"
|
||||
#include "core/errorhelper.h"
|
||||
#include "core/file.h"
|
||||
#include "core/membuffer.h"
|
||||
#include "core/subsurface-string.h"
|
||||
#include "core/save-profiledata.h"
|
||||
#include "core/version.h"
|
||||
#include <errno.h>
|
||||
|
||||
|
@ -41,45 +42,45 @@ static void put_video_time(struct membuffer *b, int secs)
|
|||
put_format(b, "%d:%02d:%02d.000,", hours, mins, secs);
|
||||
}
|
||||
|
||||
static void put_pd(struct membuffer *b, const struct plot_info *pi, int idx)
|
||||
static void put_pd(struct membuffer *b, const struct plot_info &pi, int idx)
|
||||
{
|
||||
const struct plot_data *entry = pi->entry + idx;
|
||||
const struct plot_data &entry = pi.entry[idx];
|
||||
|
||||
put_int(b, entry->in_deco);
|
||||
put_int(b, entry->sec);
|
||||
for (int c = 0; c < pi->nr_cylinders; c++) {
|
||||
put_int(b, entry.in_deco);
|
||||
put_int(b, entry.sec);
|
||||
for (int c = 0; c < pi.nr_cylinders; c++) {
|
||||
put_int(b, get_plot_sensor_pressure(pi, idx, c));
|
||||
put_int(b, get_plot_interpolated_pressure(pi, idx, c));
|
||||
}
|
||||
put_int(b, entry->temperature);
|
||||
put_int(b, entry->depth);
|
||||
put_int(b, entry->ceiling);
|
||||
put_int(b, entry.temperature);
|
||||
put_int(b, entry.depth);
|
||||
put_int(b, entry.ceiling);
|
||||
for (int i = 0; i < 16; i++)
|
||||
put_int(b, entry->ceilings[i]);
|
||||
put_int(b, entry.ceilings[i]);
|
||||
for (int i = 0; i < 16; i++)
|
||||
put_int(b, entry->percentages[i]);
|
||||
put_int(b, entry->ndl);
|
||||
put_int(b, entry->tts);
|
||||
put_int(b, entry->rbt);
|
||||
put_int(b, entry->stoptime);
|
||||
put_int(b, entry->stopdepth);
|
||||
put_int(b, entry->cns);
|
||||
put_int(b, entry->smoothed);
|
||||
put_int(b, entry->sac);
|
||||
put_int(b, entry->running_sum);
|
||||
put_double(b, entry->pressures.o2);
|
||||
put_double(b, entry->pressures.n2);
|
||||
put_double(b, entry->pressures.he);
|
||||
put_int(b, entry->o2pressure.mbar);
|
||||
put_int(b, entry.percentages[i]);
|
||||
put_int(b, entry.ndl);
|
||||
put_int(b, entry.tts);
|
||||
put_int(b, entry.rbt);
|
||||
put_int(b, entry.stoptime);
|
||||
put_int(b, entry.stopdepth);
|
||||
put_int(b, entry.cns);
|
||||
put_int(b, entry.smoothed);
|
||||
put_int(b, entry.sac);
|
||||
put_int(b, entry.running_sum);
|
||||
put_double(b, entry.pressures.o2);
|
||||
put_double(b, entry.pressures.n2);
|
||||
put_double(b, entry.pressures.he);
|
||||
put_int(b, entry.o2pressure.mbar);
|
||||
for (int i = 0; i < MAX_O2_SENSORS; i++)
|
||||
put_int(b, entry->o2sensor[i].mbar);
|
||||
put_int(b, entry->o2setpoint.mbar);
|
||||
put_int(b, entry->scr_OC_pO2.mbar);
|
||||
put_int(b, entry->mod);
|
||||
put_int(b, entry->ead);
|
||||
put_int(b, entry->end);
|
||||
put_int(b, entry->eadd);
|
||||
switch (entry->velocity) {
|
||||
put_int(b, entry.o2sensor[i].mbar);
|
||||
put_int(b, entry.o2setpoint.mbar);
|
||||
put_int(b, entry.scr_OC_pO2.mbar);
|
||||
put_int(b, entry.mod);
|
||||
put_int(b, entry.ead);
|
||||
put_int(b, entry.end);
|
||||
put_int(b, entry.eadd);
|
||||
switch (entry.velocity) {
|
||||
case STABLE:
|
||||
put_csv_string(b, "STABLE");
|
||||
break;
|
||||
|
@ -96,20 +97,20 @@ static void put_pd(struct membuffer *b, const struct plot_info *pi, int idx)
|
|||
put_csv_string(b, "CRAZY");
|
||||
break;
|
||||
}
|
||||
put_int(b, entry->speed);
|
||||
put_int(b, entry->in_deco_calc);
|
||||
put_int(b, entry->ndl_calc);
|
||||
put_int(b, entry->tts_calc);
|
||||
put_int(b, entry->stoptime_calc);
|
||||
put_int(b, entry->stopdepth_calc);
|
||||
put_int(b, entry->pressure_time);
|
||||
put_int(b, entry->heartbeat);
|
||||
put_int(b, entry->bearing);
|
||||
put_double(b, entry->ambpressure);
|
||||
put_double(b, entry->gfline);
|
||||
put_double(b, entry->surface_gf);
|
||||
put_double(b, entry->density);
|
||||
put_int_with_nl(b, entry->icd_warning ? 1 : 0);
|
||||
put_int(b, entry.speed);
|
||||
put_int(b, entry.in_deco_calc);
|
||||
put_int(b, entry.ndl_calc);
|
||||
put_int(b, entry.tts_calc);
|
||||
put_int(b, entry.stoptime_calc);
|
||||
put_int(b, entry.stopdepth_calc);
|
||||
put_int(b, entry.pressure_time);
|
||||
put_int(b, entry.heartbeat);
|
||||
put_int(b, entry.bearing);
|
||||
put_double(b, entry.ambpressure);
|
||||
put_double(b, entry.gfline);
|
||||
put_double(b, entry.surface_gf);
|
||||
put_double(b, entry.density);
|
||||
put_int_with_nl(b, entry.icd_warning ? 1 : 0);
|
||||
}
|
||||
|
||||
static void put_headers(struct membuffer *b, int nr_cylinders)
|
||||
|
@ -166,36 +167,36 @@ static void put_headers(struct membuffer *b, int nr_cylinders)
|
|||
put_csv_string_with_nl(b, "icd_warning");
|
||||
}
|
||||
|
||||
static void put_st_event(struct membuffer *b, struct plot_data *entry, int offset, int length)
|
||||
static void put_st_event(struct membuffer *b, const plot_data &entry, const plot_data &next_entry, int offset, int length)
|
||||
{
|
||||
double value;
|
||||
int decimals;
|
||||
const char *unit;
|
||||
|
||||
if (entry->sec < offset || entry->sec > offset + length)
|
||||
if (entry.sec < offset || entry.sec > offset + length)
|
||||
return;
|
||||
|
||||
put_format(b, "Dialogue: 0,");
|
||||
put_video_time(b, entry->sec - offset);
|
||||
put_video_time(b, (entry+1)->sec - offset < length ? (entry+1)->sec - offset : length);
|
||||
put_video_time(b, entry.sec - offset);
|
||||
put_video_time(b, next_entry.sec - offset < length ? next_entry.sec - offset : length);
|
||||
put_format(b, "Default,,0,0,0,,");
|
||||
put_format(b, "%d:%02d ", FRACTION_TUPLE(entry->sec, 60));
|
||||
value = get_depth_units(entry->depth, &decimals, &unit);
|
||||
put_format(b, "%d:%02d ", FRACTION_TUPLE(entry.sec, 60));
|
||||
value = get_depth_units(entry.depth, &decimals, &unit);
|
||||
put_format(b, "D=%02.2f %s ", value, unit);
|
||||
if (entry->temperature) {
|
||||
value = get_temp_units(entry->temperature, &unit);
|
||||
if (entry.temperature) {
|
||||
value = get_temp_units(entry.temperature, &unit);
|
||||
put_format(b, "T=%.1f%s ", value, unit);
|
||||
}
|
||||
// Only show NDL if it is not essentially infinite, show TTS for mandatory stops.
|
||||
if (entry->ndl_calc < 3600) {
|
||||
if (entry->ndl_calc > 0)
|
||||
put_format(b, "NDL=%d:%02d ", FRACTION_TUPLE(entry->ndl_calc, 60));
|
||||
if (entry.ndl_calc < 3600) {
|
||||
if (entry.ndl_calc > 0)
|
||||
put_format(b, "NDL=%d:%02d ", FRACTION_TUPLE(entry.ndl_calc, 60));
|
||||
else
|
||||
if (entry->tts_calc > 0)
|
||||
put_format(b, "TTS=%d:%02d ", FRACTION_TUPLE(entry->tts_calc, 60));
|
||||
if (entry.tts_calc > 0)
|
||||
put_format(b, "TTS=%d:%02d ", FRACTION_TUPLE(entry.tts_calc, 60));
|
||||
}
|
||||
if (entry->surface_gf > 0.0) {
|
||||
put_format(b, "sGF=%.1f%% ", entry->surface_gf);
|
||||
if (entry.surface_gf > 0.0) {
|
||||
put_format(b, "sGF=%.1f%% ", entry.surface_gf);
|
||||
}
|
||||
put_format(b, "\n");
|
||||
}
|
||||
|
@ -204,30 +205,25 @@ static void save_profiles_buffer(struct membuffer *b, bool select_only)
|
|||
{
|
||||
int i;
|
||||
struct dive *dive;
|
||||
struct plot_info pi;
|
||||
struct deco_state *planner_deco_state = NULL;
|
||||
|
||||
init_plot_info(&pi);
|
||||
for_each_dive(i, dive) {
|
||||
if (select_only && !dive->selected)
|
||||
continue;
|
||||
create_plot_info_new(dive, &dive->dc, &pi, planner_deco_state);
|
||||
plot_info pi = create_plot_info_new(dive, &dive->dc, planner_deco_state);
|
||||
put_headers(b, pi.nr_cylinders);
|
||||
|
||||
for (int i = 0; i < pi.nr; i++)
|
||||
put_pd(b, &pi, i);
|
||||
put_pd(b, pi, i);
|
||||
put_format(b, "\n");
|
||||
free_plot_info_data(&pi);
|
||||
}
|
||||
}
|
||||
|
||||
void save_subtitles_buffer(struct membuffer *b, struct dive *dive, int offset, int length)
|
||||
{
|
||||
struct plot_info pi;
|
||||
struct deco_state *planner_deco_state = NULL;
|
||||
|
||||
init_plot_info(&pi);
|
||||
create_plot_info_new(dive, &dive->dc, &pi, planner_deco_state);
|
||||
plot_info pi = create_plot_info_new(dive, &dive->dc, planner_deco_state);
|
||||
|
||||
put_format(b, "[Script Info]\n");
|
||||
put_format(b, "; Script generated by Subsurface %s\n", subsurface_canonical_version());
|
||||
|
@ -236,12 +232,9 @@ void save_subtitles_buffer(struct membuffer *b, struct dive *dive, int offset, i
|
|||
put_format(b, "Style: Default,Arial,12,&Hffffff,&Hffffff,&H0,&H0,0,0,0,0,100,100,0,0,1,1,0,7,10,10,10,0\n\n");
|
||||
put_format(b, "[Events]\nFormat: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\n");
|
||||
|
||||
for (int i = 0; i < pi.nr; i++) {
|
||||
put_st_event(b, &pi.entry[i], offset, length);
|
||||
}
|
||||
for (int i = 0; i + 1 < pi.nr; i++)
|
||||
put_st_event(b, pi.entry[i], pi.entry[i + 1], offset, length);
|
||||
put_format(b, "\n");
|
||||
|
||||
free_plot_info_data(&pi);
|
||||
}
|
||||
|
||||
int save_profiledata(const char *filename, bool select_only)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "profile-widget/divecartesianaxis.h"
|
||||
#include "profile-widget/divepixmapcache.h"
|
||||
#include "profile-widget/animationfunctions.h"
|
||||
#include "core/dive.h"
|
||||
#include "core/event.h"
|
||||
#include "core/eventtype.h"
|
||||
#include "core/format.h"
|
||||
|
@ -177,9 +178,9 @@ void DiveEventItem::eventVisibilityChanged(const QString&, bool)
|
|||
static int depthAtTime(const plot_info &pi, duration_t time)
|
||||
{
|
||||
// Do a binary search for the timestamp
|
||||
auto it = std::lower_bound(pi.entry, pi.entry + pi.nr, time,
|
||||
auto it = std::lower_bound(pi.entry.begin(), pi.entry.end(), time,
|
||||
[](const plot_data &d1, duration_t t) { return d1.sec < t.seconds; });
|
||||
if (it == pi.entry + pi.nr || it->sec != time.seconds) {
|
||||
if (it == pi.entry.end() || it->sec != time.seconds) {
|
||||
qWarning("can't find a spot in the dataModel");
|
||||
return DEPTH_NOT_FOUND;
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ void AbstractProfilePolygonItem::clipStop(double &x, double &y, double prev_x, d
|
|||
|
||||
std::pair<double, double> AbstractProfilePolygonItem::getPoint(int i) const
|
||||
{
|
||||
const struct plot_data *data = pInfo.entry;
|
||||
const auto &data = pInfo.entry;
|
||||
double x = data[i].sec;
|
||||
double y = accessor(data[i]);
|
||||
|
||||
|
@ -121,7 +121,7 @@ void DiveProfileItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *o
|
|||
pen.setCosmetic(true);
|
||||
pen.setWidth(2);
|
||||
QPolygonF poly = polygon();
|
||||
const struct plot_data *data = pInfo.entry;
|
||||
const auto &data = pInfo.entry;
|
||||
// This paints the colors of the velocities.
|
||||
for (int i = from + 1; i < to; i++) {
|
||||
QColor color = getColor((color_index_t)(VELOCITY_COLORS_START_IDX + data[i].velocity));
|
||||
|
@ -150,7 +150,7 @@ void DiveProfileItem::replot(const dive *d, int from, int to, bool in_planner)
|
|||
/* Show any ceiling we may have encountered */
|
||||
if (prefs.dcceiling && !prefs.redceiling) {
|
||||
QPolygonF p = polygon();
|
||||
plot_data *entry = pInfo.entry + to - 1;
|
||||
auto entry = pInfo.entry.begin() + (to - 1);
|
||||
for (int i = to - 1; i >= from; i--, entry--) {
|
||||
if (!entry->in_deco) {
|
||||
/* not in deco implies this is a safety stop, no ceiling */
|
||||
|
@ -176,7 +176,7 @@ void DiveProfileItem::replot(const dive *d, int from, int to, bool in_planner)
|
|||
const int half_interval = vAxis.getMinLabelDistance(hAxis);
|
||||
const int min_depth = 2000; // in mm
|
||||
const int min_prominence = 2000; // in mm (should this adapt to depth range?)
|
||||
const plot_data *data = pInfo.entry;
|
||||
const auto &data = pInfo.entry;
|
||||
const int max_peaks = (data[to - 1].sec - data[from].sec) / half_interval + 1;
|
||||
struct Peak {
|
||||
int range_from;
|
||||
|
@ -185,7 +185,7 @@ void DiveProfileItem::replot(const dive *d, int from, int to, bool in_planner)
|
|||
};
|
||||
std::vector<Peak> stack;
|
||||
stack.reserve(max_peaks);
|
||||
int highest_peak = std::max_element(data + from, data + to, comp_depth) - data;
|
||||
int highest_peak = std::max_element(data.begin() + from, data.begin() + to, comp_depth) - data.begin();
|
||||
if (data[highest_peak].depth < min_depth)
|
||||
return;
|
||||
stack.push_back(Peak{ from, to, highest_peak });
|
||||
|
@ -210,7 +210,7 @@ void DiveProfileItem::replot(const dive *d, int from, int to, bool in_planner)
|
|||
// Continue search until peaks reach the minimum prominence (height from valley).
|
||||
for ( ; new_from + 3 < act_peak.range_to; ++new_from) {
|
||||
if (data[new_from].depth >= data[valley].depth + min_prominence) {
|
||||
int new_peak = std::max_element(data + new_from, data + act_peak.range_to, comp_depth) - data;
|
||||
int new_peak = std::max_element(data.begin() + new_from, data.begin() + act_peak.range_to, comp_depth) - data.begin();
|
||||
if (data[new_peak].depth < min_depth)
|
||||
break;
|
||||
stack.push_back(Peak{ new_from, act_peak.range_to, new_peak });
|
||||
|
@ -236,7 +236,7 @@ void DiveProfileItem::replot(const dive *d, int from, int to, bool in_planner)
|
|||
// Continue search until peaks reach the minimum prominence (height from valley).
|
||||
for ( ; new_to >= act_peak.range_from + 3; --new_to) {
|
||||
if (data[new_to].depth >= data[valley].depth + min_prominence) {
|
||||
int new_peak = std::max_element(data + act_peak.range_from, data + new_to, comp_depth) - data;
|
||||
int new_peak = std::max_element(data.begin() + act_peak.range_from, data.begin() + new_to, comp_depth) - data.begin();
|
||||
if (data[new_peak].depth < min_depth)
|
||||
break;
|
||||
stack.push_back(Peak{ act_peak.range_from, new_to, new_peak });
|
||||
|
@ -533,17 +533,17 @@ void DiveGasPressureItem::replot(const dive *d, int fromIn, int toIn, bool in_pl
|
|||
segments.clear();
|
||||
|
||||
for (int i = from; i < to; i++) {
|
||||
const struct plot_data *entry = pInfo.entry + i;
|
||||
auto entry = pInfo.entry.begin() + i;
|
||||
|
||||
for (int cyl = 0; cyl < pInfo.nr_cylinders; cyl++) {
|
||||
double mbar = static_cast<double>(get_plot_pressure(&pInfo, i, cyl));
|
||||
double mbar = static_cast<double>(get_plot_pressure(pInfo, i, cyl));
|
||||
double time = static_cast<double>(entry->sec);
|
||||
|
||||
if (mbar < 1.0)
|
||||
continue;
|
||||
|
||||
if (i == from && i < to - 1) {
|
||||
double mbar2 = static_cast<double>(get_plot_pressure(&pInfo, i+1, cyl));
|
||||
double mbar2 = static_cast<double>(get_plot_pressure(pInfo, i+1, cyl));
|
||||
double time2 = static_cast<double>(entry[1].sec);
|
||||
if (mbar2 < 1.0)
|
||||
continue;
|
||||
|
@ -551,7 +551,7 @@ void DiveGasPressureItem::replot(const dive *d, int fromIn, int toIn, bool in_pl
|
|||
}
|
||||
|
||||
if (i == to - 1 && i > from) {
|
||||
double mbar2 = static_cast<double>(get_plot_pressure(&pInfo, i-1, cyl));
|
||||
double mbar2 = static_cast<double>(get_plot_pressure(pInfo, i-1, cyl));
|
||||
double time2 = static_cast<double>(entry[-1].sec);
|
||||
if (mbar2 < 1.0)
|
||||
continue;
|
||||
|
|
|
@ -212,7 +212,7 @@ void ToolTipItem::setPlotInfo(const plot_info &plot)
|
|||
|
||||
void ToolTipItem::clearPlotInfo()
|
||||
{
|
||||
memset(&pInfo, 0, sizeof(pInfo));
|
||||
pInfo = plot_info();
|
||||
}
|
||||
|
||||
void ToolTipItem::setTimeAxis(DiveCartesianAxis *axis)
|
||||
|
@ -231,7 +231,7 @@ void ToolTipItem::refresh(const dive *d, const QPointF &pos, bool inPlanner)
|
|||
lastTime = time;
|
||||
clear();
|
||||
|
||||
auto [idx, lines] = get_plot_details_new(d, &pInfo, time);
|
||||
auto [idx, lines] = get_plot_details_new(d, pInfo, time);
|
||||
|
||||
tissues.fill();
|
||||
painter.setPen(QColor(0, 0, 0, 0));
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "diveprofileitem.h"
|
||||
#include "divetextitem.h"
|
||||
#include "tankitem.h"
|
||||
#include "core/dive.h"
|
||||
#include "core/device.h"
|
||||
#include "core/divecomputer.h"
|
||||
#include "core/event.h"
|
||||
|
@ -151,8 +152,6 @@ ProfileScene::ProfileScene(double dpr, bool printMode, bool isGrayscale) :
|
|||
tankItem(new TankItem(*timeAxis, dpr)),
|
||||
pixmaps(getDivePixmaps(dpr))
|
||||
{
|
||||
init_plot_info(&plotInfo);
|
||||
|
||||
setSceneRect(0, 0, 100, 100);
|
||||
setItemIndexMethod(QGraphicsScene::NoIndex);
|
||||
|
||||
|
@ -188,7 +187,6 @@ ProfileScene::ProfileScene(double dpr, bool printMode, bool isGrayscale) :
|
|||
|
||||
ProfileScene::~ProfileScene()
|
||||
{
|
||||
free_plot_info_data(&plotInfo);
|
||||
}
|
||||
|
||||
void ProfileScene::clear()
|
||||
|
@ -201,7 +199,7 @@ void ProfileScene::clear()
|
|||
// the DiveEventItems
|
||||
qDeleteAll(eventItems);
|
||||
eventItems.clear();
|
||||
free_plot_info_data(&plotInfo);
|
||||
plotInfo = plot_info();
|
||||
empty = true;
|
||||
}
|
||||
|
||||
|
@ -454,7 +452,7 @@ void ProfileScene::plotDive(const struct dive *dIn, int dcIn, DivePlannerPointsM
|
|||
* create_plot_info_new() automatically frees old plot data.
|
||||
*/
|
||||
if (!keepPlotInfo)
|
||||
create_plot_info_new(d, currentdc, &plotInfo, planner_ds);
|
||||
plotInfo = create_plot_info_new(d, currentdc, planner_ds);
|
||||
|
||||
bool hasHeartBeat = plotInfo.maxhr;
|
||||
// For mobile we might want to turn of some features that are normally shown.
|
||||
|
@ -466,7 +464,7 @@ void ProfileScene::plotDive(const struct dive *dIn, int dcIn, DivePlannerPointsM
|
|||
updateVisibility(hasHeartBeat, simplified);
|
||||
updateAxes(hasHeartBeat, simplified);
|
||||
|
||||
int newMaxtime = get_maxtime(&plotInfo);
|
||||
int newMaxtime = get_maxtime(plotInfo);
|
||||
if (calcMax || newMaxtime > maxtime)
|
||||
maxtime = newMaxtime;
|
||||
|
||||
|
@ -474,7 +472,7 @@ void ProfileScene::plotDive(const struct dive *dIn, int dcIn, DivePlannerPointsM
|
|||
* when we are dragging the handler to plan / add dive.
|
||||
* otherwhise, update normally.
|
||||
*/
|
||||
int newMaxDepth = get_maxdepth(&plotInfo);
|
||||
int newMaxDepth = get_maxdepth(plotInfo);
|
||||
if (!calcMax) {
|
||||
if (maxdepth < newMaxDepth)
|
||||
maxdepth = newMaxDepth;
|
||||
|
@ -509,18 +507,18 @@ void ProfileScene::plotDive(const struct dive *dIn, int dcIn, DivePlannerPointsM
|
|||
// Find first and last plotInfo entry
|
||||
int firstSecond = lrint(timeAxis->minimum());
|
||||
int lastSecond = lrint(timeAxis->maximum());
|
||||
auto it1 = std::lower_bound(plotInfo.entry, plotInfo.entry + plotInfo.nr, firstSecond,
|
||||
auto it1 = std::lower_bound(plotInfo.entry.begin(), plotInfo.entry.end(), firstSecond,
|
||||
[](const plot_data &d, int s)
|
||||
{ return d.sec < s; });
|
||||
auto it2 = std::lower_bound(it1, plotInfo.entry + plotInfo.nr, lastSecond,
|
||||
auto it2 = std::lower_bound(it1, plotInfo.entry.end(), lastSecond,
|
||||
[](const plot_data &d, int s)
|
||||
{ return d.sec < s; });
|
||||
if (it1 > plotInfo.entry && it1->sec > firstSecond)
|
||||
if (it1 > plotInfo.entry.begin() && it1->sec > firstSecond)
|
||||
--it1;
|
||||
if (it2 < plotInfo.entry + plotInfo.nr)
|
||||
if (it2 < plotInfo.entry.end())
|
||||
++it2;
|
||||
int from = it1 - plotInfo.entry;
|
||||
int to = it2 - plotInfo.entry;
|
||||
int from = it1 - plotInfo.entry.begin();
|
||||
int to = it2 - plotInfo.entry.begin();
|
||||
|
||||
timeAxis->updateTicks(animSpeed);
|
||||
animatedAxes.push_back(timeAxis);
|
||||
|
|
|
@ -113,7 +113,7 @@ void RulerItem2::recalculate()
|
|||
setLine(line);
|
||||
|
||||
QString text;
|
||||
for (const std::string &s: compare_samples(dive, pInfo, source->idx, dest->idx, 1)) {
|
||||
for (const std::string &s: compare_samples(dive, *pInfo, source->idx, dest->idx, 1)) {
|
||||
if (!text.isEmpty())
|
||||
text += '\n';
|
||||
text += QString::fromStdString(s);
|
||||
|
|
Loading…
Add table
Reference in a new issue