663 std::vector<ScanMetadata> scans;
665 std::vector<HitPoint> hits;
676 std::vector<std::string> hit_data_labels;
677 std::unordered_map<std::string, size_t> hit_data_label_index;
678 std::vector<std::vector<double>> hit_data_columns;
679 std::vector<std::vector<char>> hit_data_present;
683 size_t getOrCreateHitDataColumn(
const std::string &label);
687 void appendHitData(
const std::map<std::string, double> &data);
699 std::vector<GridCell> grid_cells;
704 bool force_bruteforce_LAD =
false;
706 std::vector<Triangulation> triangles;
709 std::vector<HitTable<int>> hit_tables;
712 bool hitgridcellcomputed;
715 bool triangulationcomputed;
721 std::size_t triangulation_candidate_count;
722 std::size_t triangulation_dropped_lmax;
723 std::size_t triangulation_dropped_aspect;
724 std::size_t triangulation_dropped_degenerate;
735 std::function<void(
float,
const std::string &)> progress_callback;
744 size_t synthetic_scan_memory_budget_bytes = 0;
747 static constexpr size_t SYNTHETIC_SCAN_DEFAULT_BUDGET_CPU = size_t(4) * 1024 * 1024 * 1024;
750 static constexpr size_t SYNTHETIC_SCAN_DEFAULT_BUDGET_GPU = size_t(8) * 1024 * 1024 * 1024;
757 volatile int *cancel_flag =
nullptr;
764 volatile int *synthetic_scan_progress =
nullptr;
776 void finishUnifiedRayTracing();
795 void castRaysUnified(
size_t total_rays,
helios::vec3 *ray_origins,
helios::vec3 *direction,
float *hit_t,
float *hit_fnorm,
int *hit_ID,
size_t packet_size = 1);
802 std::vector<std::vector<Triangulation>> reconstructed_triangles;
804 std::vector<std::vector<Triangulation>> reconstructed_trunk_triangles;
806 std::vector<helios::vec3> reconstructed_alphamasks_center;
807 std::vector<helios::vec2> reconstructed_alphamasks_size;
808 std::vector<helios::SphericalCoord> reconstructed_alphamasks_rotation;
809 std::vector<uint> reconstructed_alphamasks_gridcell;
810 std::string reconstructed_alphamasks_maskfile;
811 std::vector<uint> reconstructed_alphamasks_direct_flag;
813 void leafReconstructionFloodfill();
815 void backfillLeavesAlphaMask(
const std::vector<float> &leaf_size,
float leaf_aspect_ratio,
float solidfraction,
const std::vector<bool> &group_filter_flag);
817 void calculateLeafAngleCDF(
uint Nbins, std::vector<std::vector<float>> &CDF_theta, std::vector<std::vector<float>> &CDF_phi);
819 void floodfill(
size_t t, std::vector<Triangulation> &cloud_triangles, std::vector<int> &fill_flag, std::vector<std::vector<int>> &nodes,
int tag,
int depth,
int maxdepth);
830 void computeGtheta(
uint Ncells,
uint Nscans, std::vector<float> &Gtheta, std::vector<float> &Gtheta_bar);
837 bool anyScanMoving()
const;
850 void calculateLeafArea_inner(
helios::Context *
context,
int min_voxel_hits,
float element_width,
float supplied_Gtheta);
867 struct LADInversionResult {
868 float leaf_area = 0.f;
869 float LAD_variance = -1.f;
873 float var_path = 0.f;
874 float L1_element = -1.f;
875 bool converged =
false;
876 bool element_size_known =
false;
895 LADInversionResult invertLADWithVariance(
uint voxel_index,
float P,
float Gtheta,
const std::vector<float> &dr_samples,
float sum_frac_sq,
float element_width,
int min_voxel_hits,
const helios::vec3 &gridsize,
905 bool ciValidPimont(
float L,
float L1,
int N,
float confidence_level)
const;
913 bool isMultiReturnData()
const;
920 struct BeamGrouping {
922 std::vector<uint> beam_members;
923 std::vector<uint> beam_offsets;
927 return beam_offsets[k + 1] - beam_offsets[k];
936 BeamGrouping groupHitsByTimestamp(
const std::vector<uint> &scan_indices)
const;
945 struct VoxelLattice {
950 float rotation = 0.f;
952 std::vector<int> ijk_to_index;
958 VoxelLattice detectVoxelLattice()
const;
975 static void accumulateBeamCell(
const uint *return_indices,
size_t Nreturns,
const std::vector<float> &dr,
const std::vector<uint> &hit_location,
float &P_equal_numerator,
float &P_equal_denominator,
float &P_equal_sumsq,
976 std::vector<float> &dr_array_cell);
987 std::vector<uint> loadTreeQSM_impl(
helios::Context *
context,
const std::string &filename,
uint radial_subdivisions,
bool use_colormap,
const std::string &colormap_or_texture);
996 std::vector<helios::vec3> gapfillMisses_timestamp(
uint scanID,
const bool gapfill_grid_only,
const bool add_flags);
1012 std::vector<helios::vec3> gapfillMisses_rowcolumn(
uint scanID,
const bool add_flags);
1022 static int selfTest(
int argc = 0,
char **argv =
nullptr);
1024 void validateRayDirections();
1121 float pulse_rate_hz,
double t0 = 0.0);
1142 float pulse_rate_hz,
double t0 = 0.0);
1180 uint addScanSpinning(
const std::vector<float> &beamElevationAngles,
float azimuthStep_rad,
float pulse_rate_hz,
const std::vector<double> &traj_t,
const std::vector<helios::vec3> &traj_pos,
const std::vector<helios::vec4> &traj_quat,
1181 const helios::vec3 &lever_arm,
const helios::vec3 &boresight_rpy,
float exitDiameter,
float beamDivergence,
float rangeNoiseStdDev,
float angleNoiseStdDev,
1182 const std::vector<std::string> &columnFormat = {
"x",
"y",
"z"},
double t0 = 0.0);
1205 uint addScanSpinning(
const std::vector<float> &beamElevationAngles,
float azimuthStep_rad,
float pulse_rate_hz,
const std::vector<double> &traj_t,
const std::vector<helios::vec3> &traj_pos,
const std::vector<helios::vec3> &traj_rpy,
1206 const helios::vec3 &lever_arm,
const helios::vec3 &boresight_rpy,
float exitDiameter,
float beamDivergence,
float rangeNoiseStdDev,
float angleNoiseStdDev,
1207 const std::vector<std::string> &columnFormat = {
"x",
"y",
"z"},
double t0 = 0.0);
1236 uint addScanMovingRaster(
uint Ntheta,
float thetaMin,
float thetaMax,
uint Nphi,
float phiMin,
float phiMax,
float pulse_rate_hz,
const std::vector<double> &traj_t,
const std::vector<helios::vec3> &traj_pos,
1237 const std::vector<helios::vec4> &traj_quat,
const helios::vec3 &lever_arm,
const helios::vec3 &boresight_rpy,
float exitDiameter,
float beamDivergence,
float rangeNoiseStdDev,
float angleNoiseStdDev,
1238 const std::vector<std::string> &columnFormat = {
"x",
"y",
"z"},
double t0 = 0.0);
1277 uint addScanRisley(
const std::vector<RisleyPrism> &prisms,
double refractive_index_air,
float pulse_rate_hz,
const std::vector<double> &traj_t,
const std::vector<helios::vec3> &traj_pos,
const std::vector<helios::vec4> &traj_quat,
1278 const helios::vec3 &lever_arm,
const helios::vec3 &boresight_rpy,
float exitDiameter,
float beamDivergence,
float rangeNoiseStdDev,
float angleNoiseStdDev,
const std::vector<std::string> &columnFormat = {
"x",
"y",
"z"},
1302 uint addScanRisley(
const std::vector<RisleyPrism> &prisms,
double refractive_index_air,
float pulse_rate_hz,
const std::vector<double> &traj_t,
const std::vector<helios::vec3> &traj_pos,
const std::vector<helios::vec3> &traj_rpy,
1303 const helios::vec3 &lever_arm,
const helios::vec3 &boresight_rpy,
float exitDiameter,
float beamDivergence,
float rangeNoiseStdDev,
float angleNoiseStdDev,
const std::vector<std::string> &columnFormat = {
"x",
"y",
"z"},
1641 void getHitDataColumn(
const char *label, std::vector<double> &data,
double absent_value = -9999)
const;
1785 void loadXML(
const char *filename);
1792 void loadXML(
const char *filename,
bool load_grid_only);
2046 void xyzFilter(
float xmin,
float xmax,
float ymin,
float ymax,
float zmin,
float zmax);
2059 void xyzFilter(
float xmin,
float xmax,
float ymin,
float ymax,
float zmin,
float zmax,
bool deleteOutside);
2076 void scalarFilter(
const char *scalar_field,
float threshold,
const char *comparator);
2129 void triangulateHitPoints(
float Lmax,
float max_aspect_ratio,
const char *scalar_field,
float threshold,
const char *comparator);
2154 void setExternalTriangulation(
const std::vector<helios::vec3> &triangle_vertices,
const std::vector<int> &scanIDs);
2447 bool getGroupLADConfidenceInterval(
const std::vector<uint> &indices,
float confidence_level,
float &mean_lad,
float &lower,
float &upper)
const;
2469 std::vector<helios::vec3>
gapfillMisses(
uint scanID,
const bool gapfill_grid_only,
const bool add_flags);
2478 force_bruteforce_LAD = force;
2546 [[deprecated(
"Use calculateLeafArea() instead. GPU functionality is now provided by the CollisionDetection plugin.")]]
2556 [[deprecated(
"Use calculateLeafArea(context, min_voxel_hits) instead. GPU functionality is now provided by the CollisionDetection plugin.")]]
2587 void leafReconstructionAlphaMask(
float minimum_leaf_group_area,
float maximum_leaf_group_area,
float leaf_aspect_ratio,
const char *mask_file);
2597 void leafReconstructionAlphaMask(
float minimum_leaf_group_area,
float maximum_leaf_group_area,
float leaf_aspect_ratio,
float leaf_length_constant,
const char *mask_file);