17 #include <laszip/laszip_api.h>
19 #include <QDataStream>
26 dataStream.setByteOrder(QDataStream::ByteOrder::LittleEndian);
29 dataStream.skipRawData(2);
30 dataStream >> dataType >> extraScalarField.
options;
31 dataStream.readRawData(extraScalarField.
name, 32);
32 dataStream.skipRawData(4);
33 dataStream.readRawData(
reinterpret_cast<char*
>(extraScalarField.
noData), 3 * 8);
34 dataStream.readRawData(
reinterpret_cast<char*
>(extraScalarField.
mins), 3 * 8);
35 dataStream.readRawData(
reinterpret_cast<char*
>(extraScalarField.
maxs), 3 * 8);
36 dataStream >> extraScalarField.
scales[0] >> extraScalarField.
scales[1] >> extraScalarField.
scales[2];
37 dataStream >> extraScalarField.
offsets[0] >> extraScalarField.
offsets[1] >> extraScalarField.
offsets[2];
38 dataStream.readRawData(
reinterpret_cast<char*
>(extraScalarField.
description), 32);
41 extraScalarField.
type = std::get<0>(type_and_dim_size);
42 extraScalarField.
dimensions = std::get<1>(type_and_dim_size);
49 dataStream.setByteOrder(QDataStream::ByteOrder::LittleEndian);
52 dataStream << emptyByte << emptyByte;
54 dataStream.writeRawData(extraScalarField.
name, 32);
55 dataStream << emptyByte << emptyByte << emptyByte << emptyByte;
56 dataStream.writeRawData(
reinterpret_cast<const char*
>(extraScalarField.
noData), 3 * 8);
57 dataStream.writeRawData(
reinterpret_cast<const char*
>(extraScalarField.
mins), 3 * 8);
58 dataStream.writeRawData(
reinterpret_cast<const char*
>(extraScalarField.
maxs), 3 * 8);
59 dataStream << extraScalarField.
scales[0] << extraScalarField.
scales[1] << extraScalarField.
scales[2];
60 dataStream << extraScalarField.
offsets[0] << extraScalarField.
offsets[1] << extraScalarField.
offsets[2];
61 dataStream.writeRawData(
reinterpret_cast<const char*
>(extraScalarField.
description), 32);
66 std::tuple<LasExtraScalarField::DataType, LasExtraScalarField::DimensionSize>
118 dataType = DataType::i32;
124 dataType = DataType::f32;
127 dataType = DataType::f64;
131 return {dataType, dimSize};
140 return sizeof(uint8_t);
142 return sizeof(uint16_t);
144 return sizeof(uint32_t);
146 return sizeof(uint64_t);
148 return sizeof(int8_t);
150 return sizeof(int16_t);
152 return sizeof(int32_t);
154 return sizeof(int64_t);
156 return sizeof(float);
158 return sizeof(double);
163 Q_ASSERT_X(
false,
"elementSize",
"Unhandled data type");
177 std::vector<LasExtraScalarField>
180 auto* extraBytesVlr = std::find_if(laszipHeader.vlrs,
181 laszipHeader.vlrs + laszipHeader.number_of_variable_length_records,
183 if (extraBytesVlr < laszipHeader.vlrs + laszipHeader.number_of_variable_length_records)
190 std::vector<LasExtraScalarField>
198 std::vector<LasExtraScalarField> info;
199 QByteArray data(
reinterpret_cast<char*
>(extraBytesVlr.data), extraBytesVlr.record_length_after_header);
200 QDataStream dataStream(data);
202 int numExtraFields = extraBytesVlr.record_length_after_header / 192;
205 for (
int j = 0; j < numExtraFields; ++j)
208 dataStream >> ebInfo;
211 if (ebInfo.
type != DataType::Undocumented && ebInfo.
type != ebInfo.DataType::Invalid)
213 info.push_back(ebInfo);
217 CVLog::Warning(
"Undocumented or invalid Extra Bytes are not supported");
221 CVLog::Print(
"[LAS] Extra Bytes: Name: '%s', Type: %s -> Size %d, Offset %d",
303 const vector<LasExtraScalarField>& extraFields)
305 strcpy(vlr.user_id,
"LASF_Spec");
307 vlr.record_length_after_header = 192 *
static_cast<laszip_U16
>(extraFields.size());
308 std::fill(vlr.description, vlr.description + 32, 0);
309 vlr.data =
new laszip_U8[vlr.record_length_after_header];
311 QByteArray byteArray;
312 byteArray.resize(vlr.record_length_after_header);
313 QDataStream dataStream(&byteArray, QIODevice::WriteOnly);
316 dataStream << extraScalarField;
318 Q_ASSERT(byteArray.size() == vlr.record_length_after_header);
319 std::copy(byteArray.begin(), byteArray.end(), vlr.data);
324 Q_ASSERT(
type != DataType::Invalid);
325 uint8_t code =
static_cast<uint8_t
>(
type);
335 return "Undocumented";
364 return std::accumulate(extraScalarFields.begin(),
365 extraScalarFields.end(),
368 { return sum + field.byteSize(); });
394 if (extraScalarField.numElements() > 1)
400 for (
unsigned i = 0; i < extraScalarField.numElements(); ++i)
402 snprintf(
name, 50,
"%s [%d]", extraScalarField.name, i);
406 extraScalarField.scalarFields[i] =
414 extraScalarField.scalarFields[i] =
nullptr;
420 const char* nameToSearch;
421 if (extraScalarField.ccName[0] != 0)
424 nameToSearch = extraScalarField.ccName;
428 nameToSearch = extraScalarField.name;
433 extraScalarField.scalarFields[0] =
447 {
return ptr ==
nullptr; };
448 return std::any_of(extraScalarField.scalarFields,
449 extraScalarField.scalarFields + extraScalarField.numElements(),
454 std::remove_if(extraScalarFields.begin(), extraScalarFields.end(), notAllScalarFieldWereFound);
455 extraScalarFields.erase(firstToRemove, extraScalarFields.end());
laszip_vlr laszip_vlr_struct
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
static bool Print(const char *format,...)
Prints out a formatted message in console.
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
A scalar field associated to display-related parameters.
int getScalarFieldIndexByName(const char *name) const
Returns the index of a scalar field represented by its name.
ScalarField * getScalarField(int index) const
Returns a pointer to a specific scalar field.
bool IsExtraBytesVlr(const laszip_vlr_struct &)
Returns whether the vlr describes extra bytes.