17 std::vector<LasExtraScalarField>& extraScalarFields,
19 : m_standardFields(standardScalarFields)
20 , m_extraScalarFields(extraScalarFields)
22 createScalarFieldsForExtraBytes(pointCloud);
26 const laszip_point& currentPoint)
31 switch (lasScalarField.id)
34 error = handleScalarField(lasScalarField, pointCloud, currentPoint.intensity);
37 error = handleScalarField(lasScalarField, pointCloud, currentPoint.return_number);
40 error = handleScalarField(lasScalarField, pointCloud, currentPoint.number_of_returns);
43 error = handleScalarField(lasScalarField, pointCloud, currentPoint.scan_direction_flag);
46 error = handleScalarField(lasScalarField, pointCloud, currentPoint.edge_of_flight_line);
49 error = handleScalarField(lasScalarField, pointCloud, currentPoint.classification);
52 error = handleScalarField(lasScalarField, pointCloud, currentPoint.synthetic_flag);
55 error = handleScalarField(lasScalarField, pointCloud, currentPoint.keypoint_flag);
58 error = handleScalarField(lasScalarField, pointCloud, currentPoint.withheld_flag);
61 error = handleScalarField(lasScalarField, pointCloud, currentPoint.scan_angle_rank);
64 error = handleScalarField(lasScalarField, pointCloud, currentPoint.user_data);
67 error = handleScalarField(lasScalarField, pointCloud, currentPoint.point_source_ID);
70 error = handleGpsTime(lasScalarField, pointCloud, currentPoint.gps_time);
73 error = handleScalarField(
74 lasScalarField, pointCloud, currentPoint.extended_scan_angle *
SCAN_ANGLE_SCALE);
77 error = handleScalarField(lasScalarField, pointCloud, currentPoint.extended_scanner_channel);
84 error = handleScalarField(lasScalarField, pointCloud, currentPoint.extended_classification);
87 error = handleScalarField(lasScalarField, pointCloud, currentPoint.extended_return_number);
90 error = handleScalarField(lasScalarField, pointCloud, currentPoint.extended_number_of_returns);
93 error = handleScalarField(lasScalarField, pointCloud, currentPoint.rgb[3]);
110 uint16_t currentOredRGB = currentPoint.rgb[0] | currentPoint.rgb[1] | currentPoint.rgb[2];
111 if (m_ignoreFieldsWithDefaultValues && currentOredRGB == 0)
122 if (!m_force8bitRgbMode && currentOredRGB > 255)
125 m_colorCompShift = 8;
128 if (pointCloud.
size() != 0)
131 for (
unsigned j = 0; j < pointCloud.
size() - 1; ++j)
140 auto red =
static_cast<ColorCompType>(currentPoint.rgb[0] >> m_colorCompShift);
149 const laszip_point& currentPoint)
151 if (currentPoint.num_extra_bytes <= 0 || currentPoint.extra_bytes ==
nullptr)
158 if (extraField.byteOffset + extraField.byteSize() >
static_cast<unsigned>(currentPoint.num_extra_bytes))
164 laszip_U8* dataStart = currentPoint.extra_bytes + extraField.byteOffset;
165 parseRawValues(extraField, dataStart);
166 switch (extraField.kind())
169 handleOptionsFor(extraField, m_rawValues.unsignedValues);
172 handleOptionsFor(extraField, m_rawValues.signedValues);
175 handleOptionsFor(extraField, m_rawValues.floatingValues);
182 template <
typename T>
188 if (m_ignoreFieldsWithDefaultValues && currentValue == T{})
194 if (!newSf->reserveSafe(pointCloud.
capacity()))
199 for (
unsigned j = 0; j < pointCloud.
size() - 1; ++j)
201 newSf->addElement(
static_cast<ScalarType
>(T{}));
207 sfInfo.
sf->
addElement(
static_cast<ScalarType
>(currentValue));
217 if (m_ignoreFieldsWithDefaultValues && currentValue == 0.0)
223 if (!newSf->reserveSafe(pointCloud.
capacity()))
229 if (std::isnan(m_manualTimeShiftValue))
231 timeShift =
static_cast<int64_t
>(currentValue / 10000.0) * 10000.0;
235 timeShift = m_manualTimeShiftValue;
238 double shiftedValue = currentValue - timeShift;
239 if (shiftedValue < 1.0e5)
241 CVLog::Warning(
"[LAS] Time SF has been shifted to prevent a loss of accuracy (%.2f)", timeShift);
243 else if (timeShift > 0.0)
245 CVLog::Warning(
"[LAS] Time SF has been shifted but accuracy may not be preserved (%.2f)",
250 CVLog::Warning(
"[LAS] Time SF has not been shifted. Accuracy may not be preserved.");
253 newSf->setGlobalShift(timeShift);
254 for (
unsigned j = 0; j < pointCloud.
size() - 1; ++j)
256 newSf->addElement(
static_cast<ScalarType
>(timeShift));
267 bool LasScalarFieldLoader::createScalarFieldsForExtraBytes(
ccPointCloud& pointCloud)
271 switch (extraField.numElements())
283 extraField.scalarFields[0] =
new ccScalarField(extraField.name);
286 if (!extraField.scalarFields[0]->reserveSafe(pointCloud.
capacity()))
293 for (
unsigned dimIndex{0}; dimIndex < extraField.numElements(); ++dimIndex)
298 if (!extraField.scalarFields[dimIndex]->reserveSafe(pointCloud.
capacity()))
305 if (extraField.offsetIsRelevant())
307 for (
unsigned i = 0; i < extraField.numElements(); ++i)
309 extraField.scalarFields[i]->setGlobalShift(extraField.offsets[i]);
316 template <
typename T>
317 ScalarType LasScalarFieldLoader::ParseValueOfType(uint8_t* source)
319 return static_cast<ScalarType
>(*
reinterpret_cast<T*
>(source));
322 template <
typename T,
typename V>
323 V LasScalarFieldLoader::ParseValueOfTypeAs(
const uint8_t* source)
325 return static_cast<V
>(*
reinterpret_cast<const T*
>(source));
328 void LasScalarFieldLoader::parseRawValues(
const LasExtraScalarField& extraField,
const uint8_t* dataStart)
330 for (
unsigned i = 0; i < extraField.
numElements(); ++i)
332 switch (extraField.
type)
338 m_rawValues.unsignedValues[i] = ParseValueOfTypeAs<uint8_t, uint64_t>(dataStart);
341 m_rawValues.unsignedValues[i] = ParseValueOfTypeAs<uint16_t, uint64_t>(dataStart);
344 m_rawValues.unsignedValues[i] = ParseValueOfTypeAs<uint32_t, uint64_t>(dataStart);
347 m_rawValues.unsignedValues[i] = ParseValueOfTypeAs<uint64_t, uint64_t>(dataStart);
350 m_rawValues.signedValues[i] = ParseValueOfTypeAs<int8_t, int64_t>(dataStart);
353 m_rawValues.signedValues[i] = ParseValueOfTypeAs<int16_t, int64_t>(dataStart);
356 m_rawValues.signedValues[i] = ParseValueOfTypeAs<int32_t, int64_t>(dataStart);
359 m_rawValues.signedValues[i] = ParseValueOfTypeAs<int64_t, int64_t>(dataStart);
362 m_rawValues.floatingValues[i] = ParseValueOfTypeAs<float, double>(dataStart);
365 m_rawValues.floatingValues[i] = ParseValueOfTypeAs<double, double>(dataStart);
372 template <
typename T>
373 void LasScalarFieldLoader::handleOptionsFor(
const LasExtraScalarField& extraField, T values[3])
376 for (
unsigned dimIndex = 0; dimIndex < extraField.
numElements(); ++dimIndex)
380 auto noDataValue = ParseValueOfTypeAs<T, T>(
static_cast<const uint8_t*
>(extraField.
noData[dimIndex]));
381 if (noDataValue == values[dimIndex])
388 double scaledValue = (values[dimIndex] * extraField.
scales[dimIndex]) + (extraField.
offsets[dimIndex]);
CC_FILE_ERROR
Typical I/O filter errors.
@ CC_FERR_NOT_ENOUGH_MEMORY
constexpr double SCAN_ANGLE_SCALE
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
CC_FILE_ERROR handleRGBValue(ccPointCloud &pointCloud, const laszip_point ¤tPoint)
CC_FILE_ERROR handleScalarFields(ccPointCloud &pointCloud, const laszip_point ¤tPoint)
CC_FILE_ERROR handleExtraScalarFields(ccPointCloud &pointCloud, const laszip_point ¤tPoint)
LasScalarFieldLoader(std::vector< LasScalarField > &standardScalarFields, std::vector< LasExtraScalarField > &extraScalarFields, ccPointCloud &pointCloud)
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
bool reserveTheRGBTable()
Reserves memory to store the RGB colors.
bool hasColors() const override
Returns whether colors are enabled or not.
void addRGBColor(const ecvColor::Rgb &C)
Pushes an RGB color on stack.
A scalar field associated to display-related parameters.
double getGlobalShift() const
Returns the global shift (if any)
int getScalarFieldIndexByName(const char *name) const
Returns the index of a scalar field represented by its name.
unsigned size() const override
unsigned capacity() const
Returns cloud capacity (i.e. reserved size)
void addElement(ScalarType value)
static ScalarType NaN()
Returns the specific NaN value.
unsigned char ColorCompType
Default color components type (R,G and B)
static void error(char *msg)
constexpr unsigned OVERLAP_FLAG_BIT_MASK
constexpr Rgb black(0, 0, 0)
constexpr Rgb red(MAX, 0, 0)
constexpr Rgb blue(0, 0, MAX)
constexpr Rgb green(0, MAX, 0)
const char * name() const
@ ExtendedNumberOfReturns