File: ccWaveform.h

package info (click to toggle)
cloudcompare 2.11.3-7.1
  • links: PTS
  • area: main
  • in suites: bookworm
  • size: 58,224 kB
  • sloc: cpp: 229,982; ansic: 30,723; makefile: 84; sh: 20
file content (227 lines) | stat: -rw-r--r-- 7,659 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
#ifndef CC_WAVEFORM_HEADER
#define CC_WAVEFORM_HEADER

//Local
#include "qCC_db.h"
#include "ccGLMatrix.h"
#include "ccSerializableObject.h"

//CCLib
#include <CCGeom.h>

//system
#include <cstdint>
#include <cstdlib>

//! Waveform descriptor
class QCC_DB_LIB_API WaveformDescriptor : public ccSerializableObject
{
public:
	
	//! Default constructor
	WaveformDescriptor();

	//! Difference operator
	bool operator != (const WaveformDescriptor& d) const;

	//! Equivalence operator
	bool operator == (const WaveformDescriptor& d) const { return	!(*this != d); }

	//inherited from ccSerializableObject
	bool isSerializable() const override { return true; }
	bool toFile(QFile& out) const override;
	bool fromFile(QFile& in, short dataVersion, int flags, LoadedIDMap& oldToNewIDMap) override;

	uint32_t numberOfSamples;	//!< Number of samples
	uint32_t samplingRate_ps;	//!< Sampling rate in pico seconds
	double digitizerGain;		//!< Digitizer gain (VOLTS = OFFSET + GAIN * Raw_Waveform_Amplitude)
	double digitizerOffset;		//!< Digitizer offset (VOLTS = OFFSET + GAIN * Raw_Waveform_Amplitude)
	uint8_t bitsPerSample;		//!< Number of bits per sample
};

//! Waveform
/** \warning Waveforms do not own their data!
**/
class QCC_DB_LIB_API ccWaveform : public ccSerializableObject
{
public:

	//! Default constructor
	ccWaveform(uint8_t descriptorID = 0);
	
	//! Destructor
	~ccWaveform() override = default;

	//! Returns the associated descriptor (ID)
	/** \warning A value of zero indicates that there is no associated waveform data.
	**/
	inline uint8_t descriptorID() const { return m_descriptorID; }

	//! Sets the associated descriptor (ID)
	inline void setDescriptorID(uint8_t id) { m_descriptorID = id; }

	//! Describes the waveform data
	void setDataDescription(uint64_t dataOffset, uint32_t byteCount);

	//! Returns the (raw) value of a given sample
	uint32_t getRawSample(uint32_t i, const WaveformDescriptor& descriptor, const uint8_t* dataStorage) const;

	//! Returns the (real) value of a given sample (in volts)
	double getSample(uint32_t i, const WaveformDescriptor& descriptor, const uint8_t* dataStorage) const;

	//! Returns the range of (real) samples
	double getRange(double& minVal, double& maxVal, const WaveformDescriptor& descriptor, const uint8_t* dataStorage) const;

	//! Decodes the samples and store them in a vector
	bool decodeSamples(std::vector<double>& values, const WaveformDescriptor& descriptor, const uint8_t* dataStorage) const;

	//! Exports (real) samples to an ASCII file
	bool toASCII(const QString& filename, const WaveformDescriptor& descriptor, const uint8_t* dataStorage) const;

	//! Helper: exports a series of values as an ASCII file
	static bool ToASCII(const QString& filename, std::vector<double>& values, uint32_t samplingRate_ps);

	//! Returns the sample position in 3D
	CCVector3 getSamplePos(float i, const CCVector3& P0, const WaveformDescriptor& descriptor) const;

	//! Returns the number of allocated bytes
	inline uint32_t byteCount() const { return m_byteCount; }

	//! Returns the byte offset to waveform data
	inline uint64_t dataOffset() const { return m_dataOffset; }

	//! Sets the byte offset to waveform data
	inline void setDataOffset(uint64_t offset) { m_dataOffset = offset; }

	//! Gives access to the internal data
	inline const uint8_t* data(const uint8_t* dataStorage) const { return dataStorage + m_dataOffset; }

	//! Sets the beam direction
	inline void setBeamDir(const CCVector3f& dir) { m_beamDir = dir; }

	//! Returns the beam direction
	inline const CCVector3f& beamDir() const { return m_beamDir; }

	//! Set the echo time (in picoseconds)
	inline void setEchoTime_ps(float time_ps) { m_echoTime_ps = time_ps; }

	//! Returns the echo time (in picoseconds)
	inline float echoTime_ps() const { return m_echoTime_ps; }

	//! Applies a rigid transformation (on the beam direction)
	void applyRigidTransformation(const ccGLMatrix& trans);

	//! Returns the return index
	uint8_t returnIndex() const { return m_returnIndex; }
	//! Sets the return index
	void setReturnIndex(uint8_t index) { m_returnIndex = index; }

	//inherited from ccSerializableObject
	bool isSerializable() const override { return true; }
	bool toFile(QFile& out) const override;
	bool fromFile(QFile& in, short dataVersion, int flags, LoadedIDMap& oldToNewIDMap) override;

protected: //members

	//! Waveform packet size in bytes
	/** \warning Not necessarily equal to the number of samples!
	**/
	uint32_t m_byteCount;

	//! Byte offset to waveform data
	uint64_t m_dataOffset;

	//! Laser beam direction
	/** Parametric line equation for extrapolating points along the associated waveform:
		X = X0 + X(t)
		Y = Y0 + Y(t)
		Z = Z0 + Z(t)
	**/
	CCVector3f m_beamDir;

	//! Return Point location (in picoseconds)
	/** The offset in picoseconds from the first digitized value to the location
		within the waveform packet that the associated return pulse was detected.
	**/
	float m_echoTime_ps;

	//! Wave Packet descriptor index
	/** \warning A value of zero indicates that there is no associated waveform data.
	**/
	uint8_t m_descriptorID;

	//! Return index
	uint8_t m_returnIndex;
};

//! Waveform proxy
/** For easier access to the waveform data
**/
class QCC_DB_LIB_API ccWaveformProxy
{
public:

	//! Default constructor
	ccWaveformProxy(const ccWaveform& w, const WaveformDescriptor& d, const uint8_t* storage)
		: m_w(w)
		, m_d(d)
		, m_storage(storage)
	{}

	//! Returns whether the waveform (proxy) is valid or not
	inline bool isValid() const { return m_storage && m_w.descriptorID() != 0 && m_d.numberOfSamples != 0; }

	//! Returns the associated descriptor (ID)
	/** \warning A value of zero indicates that there is no associated waveform data.
	**/
	inline uint8_t descriptorID() const { return m_w.descriptorID(); }

	//! Returns the (raw) value of a given sample
	inline uint32_t getRawSample(uint32_t i) const { return m_w.getRawSample(i, m_d, m_storage); }

	//! Returns the (real) value of a given sample (in volts)
	inline double getSample(uint32_t i) const { return m_w.getSample(i, m_d, m_storage); }

	//! Returns the range of (real) samples
	inline double getRange(double& minVal, double& maxVal) const { return m_w.getRange(minVal, maxVal, m_d, m_storage); }

	//! Decodes the samples and store them in a vector
	inline bool decodeSamples(std::vector<double>& values) const { return m_w.decodeSamples(values, m_d, m_storage); }

	//! Exports (real) samples to an ASCII file
	inline bool toASCII(const QString& filename) const { return m_w.toASCII(filename, m_d, m_storage); }

	//! Returns the sample position in 3D
	inline CCVector3 getSamplePos(float i, const CCVector3& P0) const { return m_w.getSamplePos(i, P0, m_d); }

	//! Returns the number of allocated bytes
	inline uint32_t byteCount() const { return m_w.byteCount(); }

	//! Gives access to the internal data
	inline const uint8_t* data() const { return m_w.data(m_storage); }

	//! Returns the beam direction
	inline const CCVector3f& beamDir() const { return m_w.beamDir(); }

	//! Returns the echo time (in picoseconds)
	inline float echoTime_ps() const { return m_w.echoTime_ps(); }

	//! Returns the number of samples
	inline uint32_t numberOfSamples() const { return m_d.numberOfSamples; }

	//! Returns the descriptor
	inline const WaveformDescriptor& descriptor() const { return m_d; }
	//! Returns the waveform
	inline const ccWaveform& waveform() const { return m_w; }

protected: //members

	//! Associated ccWaveform instance
	const ccWaveform& m_w;
	//! Associated descriptor
	const WaveformDescriptor& m_d;
	//! Associated storage data
	const uint8_t* m_storage;
};

#endif //CC_WAVEFORM_HEADER