Skip to content

Commit 74412ab

Browse files
committed
[1.3.42] 2025-07-30
- Split tutorials into separate files for better organization. - `detect_GPU_compute.cmake` script updated to fix some issues on Windows systems. 🚨+ NEW PLUG-IN + 🚨 - Added a new `collisiondetection` plug-in for efficiently calculating primitive and object collisions. # Context - `Context::generateColormap()` is now public. An error with the "cool" colormap was also fixed. # LiDAR - Added tutorials for several LiDAR application examples. - `LiDARcloud::addGridWireframeToVisualizer()` now has an optional argument to specify the line width. - All of the file exporting methods now try to create the output directory if it does not exist. - Updated error throwing to use `helios_runtime_error()`. - Added `LiDARcloud::loadTreeQSM()` and `LiDARcloud::loadTreeQSMColormap()` methods to load a TreeQSM output file and build it in the Context using tube objects. - Made `LiDARcloud::loadASCIIFile()` public, and modified it to take a file name rather than a parameters structure. - Added overloaded `LiDARcloud::addHitsToVisualizer()` that allows specification of the point color. # Visualizer - Added option to `Visualizer::addLine()` to be able to specify the line width. - Added option to `Visualizer::addPoint()` to be able to specify the point size. - Refactored how points are visualized to add automatic culling that speeds up rendering of large point clouds. - Broke `Visualizer.cpp` into four different files, as it was getting huge. - Fixed an issue introduced in v1.3.40 causing images to be written up-side down when using the `Visualizer::printWindow()` method. - Fixed an issue that could cause `Visualizer::printWindow()` to write black images on Linux. # Plant Architecture - Added `PlantArchitecture::writeQSMCylinderFile()` method to export the plant geometry as a TreeQSM cylinder file. - Added collision detection capabilities within the plant architecture plug-in. This is in the intial testing phase for now, and will be further developed in future versions. # Radiation - Added `RadiationModel::writeImageSegmentationMasks()` and `RadiationModel::writeImageSegmentationMasks_ObjectData()` to directly write COCO JSON segmentation masks for objects in the scene. - Moved camera-related code to separate file `RadiationCamera.cpp` to improve organization. - Many modifications to `CMakeLists.txt` file to fix an issue on Windows systems introduced in v1.3.40. - Fixed an error checking issue with camera processing pipeline functions to allow cameras with more than 3 channels. # Aerial LiDAR, LiDAR, Energy Balance, and Voxel Intersection - Some modifications to `CMakeLists.txt` to allow building with the project builder on Windows systems.
1 parent 4c2b528 commit 74412ab

756 files changed

Lines changed: 109297 additions & 109391 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

AGENTS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
- Standard C++ library include headers are listed in the file `core/include/global.h`. Check these includes to make sure you do not add unnecessary includes.
99
- Prefer descriptive variable names that 'self-document' the code.
1010
- Prefer clearer code over clever optimized code that provides only marginal performance improvements.
11+
- When implementing new function/method definitions, be aware of the organization of the source file. Don't just automatically add them at the end of the file, but keep them grouped with similar definitions if possible.
1112

1213
## Code Structure
1314
- The code is organized into a core library and plugins. The core library contains the main functionality, while plugins provide additional features.
@@ -39,6 +40,7 @@
3940
2. **Running Tests**:
4041
- For core tests: `./context_tests` (from context_selftest/build/)
4142
- For plugin tests: `./{plugin_name}_selftest` or `./{plugin_name}_tests`
43+
- If you need to run custom test code from a new .cpp file, add it to the `CMakeLists.txt` in the appropriate sample directory and rebuild.
4244

4345
3. **Common Build Issues**:
4446
- Always check compilation errors carefully for missing includes or function signature mismatches

core/CMake_project.cmake

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
option(ENABLE_OPENMP "Enable building with OpenMP" OFF)
22

3+
# Set CMake policies to avoid warnings on newer CMake versions
4+
if(POLICY CMP0074)
5+
cmake_policy(SET CMP0074 NEW)
6+
endif()
7+
if(POLICY CMP0077)
8+
cmake_policy(SET CMP0077 NEW)
9+
endif()
10+
if(POLICY CMP0076)
11+
cmake_policy(SET CMP0076 NEW)
12+
endif()
13+
314
set(CMAKE_CXX_STANDARD 17)
415
set(CMAKE_CXX_STANDARD_REQUIRED ON)
516
set(CMAKE_CXX_EXTENSIONS OFF)

core/include/Context.h

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* but WITHOUT ANY WARRANTY; without even the implied warranty of
1212
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1313
* GNU General Public License for more details.
14-
*/
14+
*/
1515

1616
#ifndef HELIOS_CONTEXT
1717
#define HELIOS_CONTEXT
@@ -2226,12 +2226,6 @@ namespace helios {
22262226

22272227
void writeDataToXMLstream(const char *data_group, const std::vector<std::string> &data_labels, void *ptr, std::ofstream &outfile) const;
22282228

2229-
std::vector<std::string> generateTexturesFromColormap(const std::string &texturefile, const std::vector<RGBcolor> &colormap_data);
2230-
2231-
std::vector<RGBcolor> generateColormap(const std::string &colormap, uint Ncolors);
2232-
2233-
std::vector<RGBcolor> generateColormap(const std::vector<helios::RGBcolor> &ctable, const std::vector<float> &cfrac, uint Ncolors);
2234-
22352229

22362230
//---------- CONTEXT INITIALIZATION FLAGS ---------//
22372231

@@ -6188,6 +6182,38 @@ namespace helios {
61886182
* \note If object data does not exist, or object data does not have type of 'std::string', the object is excluded.
61896183
*/
61906184
[[nodiscard]] std::vector<uint> filterObjectsByData(const std::vector<uint> &objIDs, const std::string &object_data_label, const std::string &filter_value) const;
6185+
6186+
//! Generates texture files by applying a colormap to an input texture image.
6187+
/**
6188+
* This function reads an existing texture file and modifies its colors based
6189+
* on a provided colormap. A new set of texture files is created, one for each
6190+
* color in the colormap. Each texture file reflects the applied color from
6191+
* the colormap while preserving the texture's original alpha values.
6192+
*
6193+
* \param[in] texturefile The path to the input texture file that will be used as the base for generating new textures.
6194+
* \param[in] colormap_data A vector containing the RGB colors that will be applied to the texture file. Each color in the colormap results in the generation of one texture file.
6195+
* \return A vector of strings, where each string is the filename of a newly generated texture file.
6196+
*/
6197+
std::vector<std::string> generateTexturesFromColormap(const std::string &texturefile, const std::vector<RGBcolor> &colormap_data);
6198+
6199+
//! Generates a colormap with a specified number of colors based on the selected colormap type
6200+
/**
6201+
* \param[in] colormap The name of the colormap to generate (e.g., "hot", "cool", "lava", etc.).
6202+
* \param[in] Ncolors The desired number of colors in the output colormap.
6203+
* \return A vector of RGBcolor objects representing the generated colormap.
6204+
*/
6205+
std::vector<RGBcolor> generateColormap(const std::string &colormap, uint Ncolors);
6206+
6207+
//! Generates a colormap of interpolated colors based on input color table and fractions.
6208+
/**
6209+
* \param[in] ctable A vector of RGB colors defining the input color points for interpolation.
6210+
* \param[in] cfrac A vector of fractional values corresponding to each color in the color table, must match the size of ctable.
6211+
* \param[in] Ncolors Desired number of output colors in the generated colormap. Must be greater than 0.
6212+
* \return A vector of RGB colors representing the generated colormap.
6213+
* \note The input vectors ctable and cfrac must have the same size, and neither can be empty. If the requested Ncolors exceeds the internal limit, it will be truncated to 9999, with a warning issued.
6214+
*/
6215+
std::vector<RGBcolor> generateColormap(const std::vector<helios::RGBcolor> &ctable, const std::vector<float> &cfrac, uint Ncolors);
6216+
61916217
};
61926218

61936219
} // namespace helios

core/include/global.h

100755100644
Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* but WITHOUT ANY WARRANTY; without even the implied warranty of
1212
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1313
* GNU General Public License for more details.
14-
*/
14+
*/
1515

1616
#ifndef HELIOS_GLOBAL
1717
#define HELIOS_GLOBAL
@@ -57,6 +57,7 @@ constexpr float PI_F = 3.14159265358979323846f;
5757
#include <type_traits>
5858
#include <unordered_map>
5959
#include <vector>
60+
#include <set>
6061

6162
#ifdef USE_OPENMP
6263
#include <omp.h>
@@ -1162,6 +1163,48 @@ namespace helios {
11621163
}
11631164
};
11641165

1166+
//! A utility struct to capture and store what is written to `std::cout`.
1167+
/**
1168+
* This struct redirects the `std::cout` stream to an internal string stream
1169+
* while an instance of the struct exists. When the struct is destroyed,
1170+
* it restores the original `std::cout` output stream. The captured output
1171+
* can be queried and cleared as needed.
1172+
*/
1173+
struct capture_cout {
1174+
std::streambuf *old_buf;
1175+
std::ostringstream captured_stream;
1176+
1177+
capture_cout() {
1178+
old_buf = std::cout.rdbuf(captured_stream.rdbuf());
1179+
}
1180+
1181+
~capture_cout() {
1182+
std::cout.rdbuf(old_buf);
1183+
}
1184+
1185+
//! Get the captured cout output as a string
1186+
std::string get_captured_output() const {
1187+
return captured_stream.str();
1188+
}
1189+
1190+
//! Check if any output has been captured
1191+
bool has_output() const {
1192+
return !captured_stream.str().empty();
1193+
}
1194+
1195+
//! Clear the captured output
1196+
void clear() {
1197+
captured_stream.str("");
1198+
captured_stream.clear();
1199+
}
1200+
1201+
//! Get the number of characters captured
1202+
size_t size() const {
1203+
return captured_stream.str().size();
1204+
}
1205+
};
1206+
1207+
11651208
//! Default null SphericalCoord that applies no rotation
11661209
extern SphericalCoord nullrotation;
11671210
//! Default null vec3 that gives the origin (0,0,0)

core/include/helios_vector_types.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* but WITHOUT ANY WARRANTY; without even the implied warranty of
1212
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1313
* GNU General Public License for more details.
14-
*/
14+
*/
1515

1616
#ifndef HELIOS_VECTOR_TYPES
1717
#define HELIOS_VECTOR_TYPES

core/lib/detect_GPU_compute.cmake

Lines changed: 48 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,33 @@
11
set(NVCC_EXECUTABLE "${CUDAToolkit_NVCC_EXECUTABLE}")
22

33
# ask nvcc for all supported GPU codes (sm_* and compute_*)
4-
execute_process( COMMAND ${NVCC_EXECUTABLE} --list-gpu-code OUTPUT_VARIABLE _nvcc_gpu_codes OUTPUT_STRIP_TRAILING_WHITESPACE )
5-
6-
# split lines into a CMake list
7-
string(REPLACE "\n" ";" _gpu_codes "${_nvcc_gpu_codes}")
8-
9-
# separate out real (sm_XX) and virtual (compute_XX) architectures
10-
set(_sm_codes "")
11-
set(_virtual_codes "")
12-
foreach(_code IN LISTS _gpu_codes)
13-
if(_code MATCHES "^sm_[0-9]+$")
14-
list(APPEND _sm_codes ${_code})
15-
elseif(_code MATCHES "^compute_[0-9]+$")
16-
list(APPEND _virtual_codes ${_code})
17-
endif()
18-
endforeach()
19-
20-
# Extract architecture numbers for CMAKE_CUDA_ARCHITECTURES
21-
set(_cuda_architectures "")
22-
foreach(_sm IN LISTS _sm_codes)
23-
# Extract the number from sm_XX
24-
string(REGEX REPLACE "sm_(.+)" "\\1" _arch_num "${_sm}")
25-
list(APPEND _cuda_architectures ${_arch_num})
26-
endforeach()
4+
execute_process( COMMAND ${NVCC_EXECUTABLE} --list-gpu-code OUTPUT_VARIABLE _nvcc_gpu_codes OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET RESULT_VARIABLE _nvcc_result)
5+
6+
if(_nvcc_result EQUAL 0)
7+
# split lines into a CMake list
8+
string(REPLACE "\n" ";" _gpu_codes "${_nvcc_gpu_codes}")
9+
10+
# separate out real (sm_XX) and virtual (compute_XX) architectures
11+
set(_sm_codes "")
12+
set(_virtual_codes "")
13+
foreach(_code IN LISTS _gpu_codes)
14+
if(_code MATCHES "^sm_[0-9]+$")
15+
list(APPEND _sm_codes ${_code})
16+
elseif(_code MATCHES "^compute_[0-9]+$")
17+
list(APPEND _virtual_codes ${_code})
18+
endif()
19+
endforeach()
20+
21+
# Extract architecture numbers for CMAKE_CUDA_ARCHITECTURES
22+
set(_cuda_architectures "")
23+
foreach(_sm IN LISTS _sm_codes)
24+
# Extract the number from sm_XX
25+
string(REGEX REPLACE "sm_(.+)" "\\1" _arch_num "${_sm}")
26+
list(APPEND _cuda_architectures ${_arch_num})
27+
endforeach()
28+
else()
29+
set(_cuda_architectures "")
30+
endif()
2731

2832
# if no architectures were detected, fall back to SM 5.0
2933
if(NOT _cuda_architectures)
@@ -35,21 +39,24 @@ endif()
3539
set(CMAKE_CUDA_ARCHITECTURES "${_cuda_architectures}")
3640

3741
# Also build gencode flags for compatibility (if needed elsewhere)
38-
set(_gencode_flags "")
39-
foreach(_sm IN LISTS _sm_codes)
40-
# derive compute_XX from sm_XX
41-
string(REGEX REPLACE "sm_(.+)" "compute_\\1" _compute "${_sm}")
42-
43-
# always emit native cubin for each SM you found
44-
list(APPEND _gencode_flags "-gencode" "arch=${_compute},code=${_sm}" )
45-
endforeach()
46-
47-
# if no architectures were detected, fall back to SM 5.0
48-
if(NOT _gencode_flags)
49-
message(WARNING "No CUDA architectures detected; defaulting to compute_50,code=sm_50")
50-
list(APPEND _gencode_flags "-gencode" "arch=compute_50,code=sm_50" )
51-
endif()
52-
53-
# append to your CUDA flags (for compatibility)
54-
string (JOIN " " _joined "${_gencode_flags}")
55-
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} ${_joined}")
42+
# NOTE: Modern CMake uses CMAKE_CUDA_ARCHITECTURES instead
43+
if(DEFINED _sm_codes)
44+
set(_gencode_flags "")
45+
foreach(_sm IN LISTS _sm_codes)
46+
# derive compute_XX from sm_XX
47+
string(REGEX REPLACE "sm_(.+)" "compute_\\1" _compute "${_sm}")
48+
49+
# always emit native cubin for each SM you found
50+
list(APPEND _gencode_flags "-gencode" "arch=${_compute},code=${_sm}" )
51+
endforeach()
52+
53+
# if no architectures were detected, fall back to SM 5.0
54+
if(NOT _gencode_flags)
55+
message(WARNING "No CUDA architectures detected; defaulting to compute_50,code=sm_50")
56+
list(APPEND _gencode_flags "-gencode" "arch=compute_50,code=sm_50" )
57+
endif()
58+
59+
# append to your CUDA flags (for compatibility with old code)
60+
string (JOIN " " _joined "${_gencode_flags}")
61+
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} ${_joined}")
62+
endif()

core/src/Context.cpp

100755100644
Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* but WITHOUT ANY WARRANTY; without even the implied warranty of
1212
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1313
* GNU General Public License for more details.
14-
*/
14+
*/
1515

1616
#include "Context.h"
1717

@@ -441,14 +441,6 @@ float Context::randn(float mean, float stddev) {
441441
}
442442

443443

444-
445-
446-
447-
448-
449-
450-
451-
452444
std::vector<uint> Context::getAllUUIDs() const {
453445
std::vector<uint> UUIDs;
454446
UUIDs.reserve(primitives.size());
@@ -1763,7 +1755,6 @@ void Context::setTileObjectSubdivisionCount(const std::vector<uint> &ObjIDs, flo
17631755
}
17641756

17651757

1766-
17671758
std::vector<uint> Context::addSphere(uint Ndivs, const vec3 &center, float radius) {
17681759
RGBcolor color = make_RGBcolor(0.f, 0.75f, 0.f); // Default color is green
17691760

@@ -2867,12 +2858,12 @@ std::vector<RGBcolor> Context::generateColormap(const std::string &colormap, uin
28672858
clocs_c.at(4) = 1.f;
28682859
} else if (colormap == "cool") {
28692860
ctable_c.resize(2);
2870-
ctable_c.at(1) = RGB::cyan;
2871-
ctable_c.at(2) = RGB::magenta;
2861+
ctable_c.at(0) = RGB::cyan;
2862+
ctable_c.at(1) = RGB::magenta;
28722863

28732864
clocs_c.resize(2);
2874-
clocs_c.at(1) = 0.f;
2875-
clocs_c.at(2) = 1.f;
2865+
clocs_c.at(0) = 0.f;
2866+
clocs_c.at(1) = 1.f;
28762867
} else if (colormap == "lava") {
28772868
ctable_c.resize(5);
28782869
ctable_c.at(0) = make_RGBcolor(0.f, 0.05f, 0.05f);

core/src/Context_data.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* but WITHOUT ANY WARRANTY; without even the implied warranty of
1212
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1313
* GNU General Public License for more details.
14-
*/
14+
*/
1515

1616
#include "Context.h"
1717

core/src/Context_fileIO.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* but WITHOUT ANY WARRANTY; without even the implied warranty of
1212
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1313
* GNU General Public License for more details.
14-
*/
14+
*/
1515

1616
#include "Context.h"
1717

core/src/Context_object.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* but WITHOUT ANY WARRANTY; without even the implied warranty of
1212
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1313
* GNU General Public License for more details.
14-
*/
14+
*/
1515

1616
#include "Context.h"
1717

@@ -2615,4 +2615,4 @@ float Cone::getVolume() const {
26152615
float h = getLength();
26162616

26172617
return PI_F * h / 3.f * (r0 * r0 + r0 * r1 + r1 * r1);
2618-
}
2618+
}

0 commit comments

Comments
 (0)