Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions raycloudtools/rayalign/rayalign.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ int rayAlign(int argc, char *argv[])
if (!cross_align && !self_align)
usage();

std::string aligned_name = cloud_a.nameStub() + "_aligned.las";
const std::string ext_a = ray::getFileNameExtension(cloud_a.name());
std::string aligned_name = cloud_a.nameStub() + "_aligned." + ext_a;
if (self_align)
{
if (!ray::alignCloudToAxes(cloud_a.name(), aligned_name))
Expand Down Expand Up @@ -79,7 +80,7 @@ int rayAlign(int argc, char *argv[])
{
alignCloud0ToCloud1(clouds, 0.5, verbose);
if (verbose)
clouds[0].save(cloud_a.nameStub() + "_coarse_aligned.las");
clouds[0].save(cloud_a.nameStub() + "_coarse_aligned." + ext_a);
}

ray::FineAlignment fineAlign(clouds, non_rigid, verbose);
Expand Down
46 changes: 37 additions & 9 deletions raycloudtools/raycolour/raycolour.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "raylib/raycloud.h"
#include "raylib/raycloudwriter.h"
#include "raylib/rayparse.h"
#include "raylib/raylaz.h"
#define STB_IMAGE_IMPLEMENTATION
#include "raylib/imageread.h"

Expand Down Expand Up @@ -54,7 +55,8 @@ void spectrumRGB(double value, ray::RGBA &colour)
}

/// Function to colour the cloud from a horizontal projection of a supplied image, stretching to match the cloud bounds.
void colourFromImage(const std::string &cloud_file, const std::string &image_file, ray::CloudWriter &writer)
void colourFromImage(const std::string &cloud_file, const std::string &image_file, ray::CloudWriter &writer,
std::vector<uint8_t> &passthrough_buf)
{
ray::Cloud::Info info;
if (!ray::Cloud::getInfo(cloud_file, info))
Expand All @@ -74,7 +76,8 @@ void colourFromImage(const std::string &cloud_file, const std::string &image_fil
<< ", stretching to fit) " << std::endl;
}

auto colour_from_image = [&bounds, &writer, &image_data, width_x, width_y, width, height, num_channels](
auto colour_from_image = [&bounds, &writer, &image_data, width_x, width_y, width, height, num_channels,
&passthrough_buf](
std::vector<Eigen::Vector3d> &starts, std::vector<Eigen::Vector3d> &ends,
std::vector<double> &times, std::vector<ray::RGBA> &colours) {
for (size_t i = 0; i < ends.size(); i++)
Expand All @@ -86,10 +89,19 @@ void colourFromImage(const std::string &cloud_file, const std::string &image_fil
colours[i].green = image_data[index + 1];
colours[i].blue = image_data[index + 2];
}
writer.writeChunk(starts, ends, times, colours);
std::vector<uint8_t> chunk_pass(passthrough_buf);
passthrough_buf.clear();
writer.writeChunk(starts, ends, times, colours, chunk_pass);
};

if (!ray::Cloud::read(cloud_file, colour_from_image))
const std::string ext = ray::getFileNameExtension(cloud_file);
if (ext == "las" || ext == "laz")
{
size_t num_bounded;
if (!ray::readLas(cloud_file, colour_from_image, num_bounded, 1.0, nullptr, 1000000, nullptr, &passthrough_buf))
usage();
}
else if (!ray::Cloud::read(cloud_file, colour_from_image))
usage();

stbi_image_free(image_data);
Expand All @@ -112,17 +124,25 @@ int rayColour(int argc, char *argv[])
usage();

std::string in_file = cloud_file.name();
const std::string out_file = cloud_file.nameStub() + "_coloured.las";
const std::string out_file = cloud_file.nameStub() + "_coloured." + ray::getFileNameExtension(cloud_file.name());
const std::string type = colour_type.selectedKey();
uint8_t split_alpha = 100;

if (type != "shape" && type != "normal" && type != "branches") // chunk loading possible for simple cases
{
const std::string ext = ray::getFileNameExtension(cloud_file.name());
uint16_t orig_extra = 0;
std::vector<uint8_t> extra_bytes_vlr;
if (ext == "las" || ext == "laz")
ray::readLasExtraBytesVlr(cloud_file.name(), orig_extra, extra_bytes_vlr);

ray::CloudWriter writer;
if (!writer.begin(out_file))
if (!writer.begin(out_file, extra_bytes_vlr))
usage();

auto colour_rays = [flat_colour, flat_alpha, &type, &col, &alpha, &writer, &split_alpha](
std::vector<uint8_t> passthrough_buf;

auto colour_rays = [flat_colour, flat_alpha, &type, &col, &alpha, &writer, &split_alpha, &passthrough_buf](
std::vector<Eigen::Vector3d> &starts, std::vector<Eigen::Vector3d> &ends,
std::vector<double> &times, std::vector<ray::RGBA> &colours) {
if (flat_colour)
Expand Down Expand Up @@ -172,12 +192,20 @@ int rayColour(int argc, char *argv[])
else
usage();
}
writer.writeChunk(starts, ends, times, colours);
std::vector<uint8_t> chunk_pass(passthrough_buf);
passthrough_buf.clear();
writer.writeChunk(starts, ends, times, colours, chunk_pass);
};

if (image_format)
{
colourFromImage(cloud_file.name(), image_file.name(), writer);
colourFromImage(cloud_file.name(), image_file.name(), writer, passthrough_buf);
}
else if (ext == "las" || ext == "laz")
{
size_t num_bounded;
if (!ray::readLas(cloud_file.name(), colour_rays, num_bounded, 1.0, nullptr, 1000000, nullptr, &passthrough_buf))
usage();
}
else if (!ray::Cloud::read(cloud_file.name(), colour_rays))
{
Expand Down
54 changes: 37 additions & 17 deletions raycloudtools/raycombine/raycombine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "raylib/rayprogressthread.h"
#include "raylib/raythreads.h"
#include "raylib/raycloudwriter.h"
#include "raylib/raylaz.h"

#include <cstdio>
#include <cstdlib>
Expand Down Expand Up @@ -116,30 +117,49 @@ int rayCombine(int argc, char *argv[])
{
config.merge_type = ray::MergeType::All;
}
std::string combined_file = output.isSet() ? output_file.name() : file_stub + "_combined.las";
const std::string combine_ext = ray::getFileNameExtension(
(threeway || threeway_concatenate) ? base_cloud.name() : cloud_files.files()[0].name());
std::string combined_file = output.isSet() ? output_file.name() : file_stub + "_combined." + combine_ext;
if (concatenate_all)
{
// Pre-read extra-byte VLR from the first input file so the writer can register them.
std::vector<uint8_t> extra_bytes_vlr;
const std::string first_file = cloud_files.files()[0].name();
const std::string first_ext = ray::getFileNameExtension(first_file);
if (first_ext == "las" || first_ext == "laz")
{
uint16_t orig_extra = 0;
ray::readLasExtraBytesVlr(first_file, orig_extra, extra_bytes_vlr);
}

ray::CloudWriter writer;
if (!writer.begin(combined_file))
if (!writer.begin(combined_file, extra_bytes_vlr))
usage();

// By maintaining these buffers below, we avoid almost all memory fragmentation
auto concatenate = [&](std::vector<Eigen::Vector3d> &starts, std::vector<Eigen::Vector3d> &ends,
std::vector<double> &times, std::vector<ray::RGBA> &colours)
{
ray::Cloud chunk;
chunk.starts = starts;
chunk.ends = ends;
chunk.colours = colours;
chunk.times = times;
writer.writeChunk(chunk);
};
for (int i = 0; i < (int)cloud_files.files().size(); i++)
{
if (!ray::Cloud::read(cloud_files.files()[i].name(), concatenate))
usage();
const std::string &fname = cloud_files.files()[i].name();
const std::string fext = ray::getFileNameExtension(fname);
std::vector<uint8_t> passthrough_buf;
auto concatenate = [&](std::vector<Eigen::Vector3d> &starts, std::vector<Eigen::Vector3d> &ends,
std::vector<double> &times, std::vector<ray::RGBA> &colours) {
std::vector<uint8_t> chunk_pass(std::move(passthrough_buf));
passthrough_buf.clear();
writer.writeChunk(starts, ends, times, colours, chunk_pass);
};
if (fext == "las" || fext == "laz")
{
size_t num_bounded;
if (!ray::readLas(fname, concatenate, num_bounded, 1.0, nullptr, 1000000, nullptr, &passthrough_buf))
usage();
}
else
{
if (!ray::Cloud::read(fname, concatenate))
usage();
}
}
writer.end();
writer.end();
return 0;
}

Expand All @@ -161,7 +181,7 @@ int rayCombine(int argc, char *argv[])
merger.mergeMultiple(clouds, &progress);
std::cout << merger.differenceCloud().rayCount() << " transients, " << merger.fixedCloud().rayCount()
<< " fixed rays." << std::endl;
merger.differenceCloud().save(file_stub + "_differences.las");
merger.differenceCloud().save(file_stub + "_differences." + combine_ext);
}

progress_thread.join();
Expand Down
10 changes: 5 additions & 5 deletions raycloudtools/raydecimate/raydecimate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,23 +63,23 @@ int rayDecimate(int argc, char *argv[])
bool res = false;
if (double_format_points)
{
res = ray::decimateSpatioTemporal(cloud_file.nameStub(), vox_width.value(), num_rays.value());
res = ray::decimateSpatioTemporal(cloud_file.name(), vox_width.value(), num_rays.value());
}
else if (quantity.selectedKey() == "cm/ray")
{
res = ray::decimateRaysSpatial(cloud_file.nameStub(), width_for_ray.value());
res = ray::decimateRaysSpatial(cloud_file.name(), width_for_ray.value());
}
else if (quantity.selectedKey() == "cm")
{
res = ray::decimateSpatial(cloud_file.nameStub(), vox_width.value());
res = ray::decimateSpatial(cloud_file.name(), vox_width.value());
}
else if (quantity.selectedKey() == "rays")
{
res = ray::decimateTemporal(cloud_file.nameStub(), num_rays.value());
res = ray::decimateTemporal(cloud_file.name(), num_rays.value());
}
else if (quantity.selectedKey() == "cm/m")
{
res = ray::decimateAngular(cloud_file.nameStub(), radius_per_length.value());
res = ray::decimateAngular(cloud_file.name(), radius_per_length.value());
}
if (!res)
usage();
Expand Down
2 changes: 1 addition & 1 deletion raycloudtools/raydenoise/raydenoise.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ int rayDenoise(int argc, char *argv[])
<< " rays removed with nearest neighbour sigma more than " << sigmas.value() << std::endl;
}

new_cloud.save(cloud_file.nameStub() + "_denoised.las");
new_cloud.save(cloud_file.nameStub() + "_denoised." + ray::getFileNameExtension(cloud_file.name()));
return 0;
}

Expand Down
8 changes: 5 additions & 3 deletions raycloudtools/raydiff/raydiff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,9 @@ int rayDiff(int argc, char *argv[])
j++;
}
}
cloud1.save(cloud1_name.nameStub() + "_diff.las");
const std::string ext1 = ray::getFileNameExtension(cloud1_name.name());
const std::string ext2 = ray::getFileNameExtension(cloud2_name.name());
cloud1.save(cloud1_name.nameStub() + "_diff." + ext1);
j = 0;
for (int i = 0; i<(int)cloud2.ends.size(); i++)
{
Expand All @@ -277,11 +279,11 @@ int rayDiff(int argc, char *argv[])
j++;
}
}
cloud2.save(cloud2_name.nameStub() + "_diff.las");
cloud2.save(cloud2_name.nameStub() + "_diff." + ext2);

if (visualise.isSet())
{
std::string command = std::string(VISUALISE_TOOL) + std::string(" ") + cloud1_name.nameStub() + "_diff.ply " + cloud2_name.nameStub() + "_diff.las";
std::string command = std::string(VISUALISE_TOOL) + std::string(" ") + cloud1_name.nameStub() + "_diff." + ext1 + " " + cloud2_name.nameStub() + "_diff." + ext2;
system(command.c_str());
}
return (int)similarity;
Expand Down
29 changes: 22 additions & 7 deletions raycloudtools/rayimport/rayimport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ void usage(int exit_code = 1)
std::cout << " --remove_start_pos - translate so first point is at 0,0,0" << std::endl;
std::cout << "rayimport pointcloudfile unbound transformfile - load unbound data (pulses that missed) from RIEGL .rxp file" << std::endl;
std::cout << " transformfile is a text file containing a 4x4 transformation matrix" << std::endl;
std::cout << "The output is a .las file of the same name (or with suffix _raycloud if the input was a .ply file)." << std::endl;
std::cout << "The output is a _raycloud.las/.laz file (preserving .laz if the input is .laz)." << std::endl;
// clang-format on
exit(exit_code);
}
Expand Down Expand Up @@ -93,16 +93,28 @@ int rayImport(int argc, char *argv[])
usage();
}

std::string save_file = cloud_file.nameStub();
if (cloud_file.nameExt() == "ply")
save_file += "_raycloud";
std::string save_file = cloud_file.nameStub() + "_raycloud";
const std::string in_ext = cloud_file.nameExt();
const std::string save_ext = (in_ext == "laz") ? "laz" : "las";
size_t num_bounded;

// Pre-read original sensor extra-byte attributes from the input LAS/LAZ header so the writer
// can register and preserve them before opening the output file.
std::vector<uint8_t> input_extra_bytes_vlr;
if (in_ext == "laz" || in_ext == "las")
{
uint16_t orig_extra = 0;
ray::readLasExtraBytesVlr(cloud_file.name(), orig_extra, input_extra_bytes_vlr);
}

ray::CloudWriter writer;
if (!writer.begin(save_file + ".las"))
if (!writer.begin(save_file + "." + save_ext, input_extra_bytes_vlr))
usage();
Eigen::Vector3d start_pos(0, 0, 0);
double min_time = std::numeric_limits<double>::max();
double max_time = std::numeric_limits<double>::lowest();
std::vector<uint8_t> all_passthrough;
size_t prev_pass_size = 0;
auto add_chunk = [&](std::vector<Eigen::Vector3d> &starts, std::vector<Eigen::Vector3d> &ends,
std::vector<double> &times, std::vector<ray::RGBA> &colours) {
if (start_pos.squaredNorm() == 0.0)
Expand Down Expand Up @@ -178,7 +190,9 @@ int rayImport(int argc, char *argv[])
c.alpha = uint8_t(0);
}
}
if (!writer.writeChunk(starts, ends, times, colours))
std::vector<uint8_t> chunk_pass(all_passthrough.begin() + prev_pass_size, all_passthrough.end());
prev_pass_size = all_passthrough.size();
if (!writer.writeChunk(starts, ends, times, colours, chunk_pass))
usage();
};

Expand Down Expand Up @@ -218,7 +232,8 @@ int rayImport(int argc, char *argv[])
}
else if (cloud_file.nameExt() == "laz" || cloud_file.nameExt() == "las")
{
if (!ray::readLas(cloud_file.name(), add_chunk, num_bounded, maximum_intensity, offset))
if (!ray::readLas(cloud_file.name(), add_chunk, num_bounded, maximum_intensity, offset, 1000000, nullptr,
&all_passthrough))
{
usage();
}
Expand Down
2 changes: 1 addition & 1 deletion raycloudtools/rayrestore/rayrestore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ int rayRestore(int argc, char *argv[])
// now apply the estimated transformation. We need to chunk save the _restored file, using the
// re-chunkloaded full_cloud_file
ray::CloudWriter writer;
if (!writer.begin(full_cloud_file.nameStub() + "_restored.las"))
if (!writer.begin(full_cloud_file.nameStub() + "_restored." + ray::getFileNameExtension(full_cloud_file.name())))
usage();
ray::Cloud chunk;

Expand Down
2 changes: 1 addition & 1 deletion raycloudtools/raysmooth/raysmooth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ int raySmooth(int argc, char *argv[])
cloud.ends[i] += normals[i] * (centroids[i] - cloud.ends[i]).dot(normals[i]);
}

cloud.save(cloud_file.nameStub() + "_smooth.las");
cloud.save(cloud_file.nameStub() + "_smooth." + ray::getFileNameExtension(cloud_file.name()));

return 0;
}
Expand Down
5 changes: 3 additions & 2 deletions raycloudtools/raysplit/raysplit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,9 @@ int raySplit(int argc, char *argv[])
usage();
}

const std::string in_name = cloud_file.nameStub() + "_inside.las";
const std::string out_name = cloud_file.nameStub() + "_outside.las";
const std::string split_ext = ray::getFileNameExtension(cloud_file.name());
const std::string in_name = cloud_file.nameStub() + "_inside." + split_ext;
const std::string out_name = cloud_file.nameStub() + "_outside." + split_ext;
const std::string rc_name = cloud_file.name(); // ray cloud name
bool res = true;

Expand Down
5 changes: 3 additions & 2 deletions raycloudtools/raytransients/raytransients.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,9 @@ int rayTransients(int argc, char *argv[])
const ray::Cloud &transient = filter.differenceCloud();
const ray::Cloud &fixed = filter.fixedCloud();

transient.save(cloud_file.nameStub() + "_transient.las");
fixed.save(cloud_file.nameStub() + "_fixed.las");
const std::string ext = ray::getFileNameExtension(cloud_file.name());
transient.save(cloud_file.nameStub() + "_transient." + ext);
fixed.save(cloud_file.nameStub() + "_fixed." + ext);
return 0;
}

Expand Down
Loading
Loading