diff --git a/extensions/pcl/src/graph/DownSamplePointsNode.cpp b/extensions/pcl/src/graph/DownSamplePointsNode.cpp index a45b1c5b..b940b36d 100644 --- a/extensions/pcl/src/graph/DownSamplePointsNode.cpp +++ b/extensions/pcl/src/graph/DownSamplePointsNode.cpp @@ -28,6 +28,10 @@ void DownSamplePointsNode::validateImpl() auto msg = fmt::format("{} requires XYZ to be present", getName()); throw InvalidPipeline(msg); } + // Needed to clear cache because fields in the pipeline may have changed + // In fact, the cache manager is no longer useful here + // To be kept/removed in some future refactor (when resolving comment in the `enqueueExecImpl`) + cacheManager.clear(); } void DownSamplePointsNode::enqueueExecImpl() diff --git a/src/CacheManager.hpp b/src/CacheManager.hpp index 6b6e6a5d..7bf22b20 100644 --- a/src/CacheManager.hpp +++ b/src/CacheManager.hpp @@ -58,6 +58,12 @@ struct CacheManager return result; } + void clear() + { + cache.clear(); + cacheAge.clear(); + } + void setUpdated(Key key) { cacheAge.at(key) = 0; } bool isLatest(Key key) const { return cacheAge.at(key) == 0; } bool contains(Key key) const { return cache.contains(key); } diff --git a/src/graph/CompactPointsNode.cpp b/src/graph/CompactPointsNode.cpp index 6027a163..b7f88c0d 100644 --- a/src/graph/CompactPointsNode.cpp +++ b/src/graph/CompactPointsNode.cpp @@ -18,6 +18,14 @@ #include #include +void CompactPointsNode::validateImpl() +{ + IPointsNodeSingleInput::validateImpl(); + // Needed to clear cache because fields in the pipeline may have changed + // In fact, the cache manager is no longer useful here + // To be kept/removed in some future refactor (when resolving comment in the `enqueueExecImpl`) + cacheManager.clear(); +} void CompactPointsNode::enqueueExecImpl() { diff --git a/src/graph/NodesCore.hpp b/src/graph/NodesCore.hpp index 5ff81c21..53ca89e9 100644 --- a/src/graph/NodesCore.hpp +++ b/src/graph/NodesCore.hpp @@ -74,6 +74,7 @@ struct CompactPointsNode : IPointsNodeSingleInput void setParameters() {} // Node + void validateImpl() override; void enqueueExecImpl() override; // Node requirements diff --git a/test/src/graph/graphCaseTest.cpp b/test/src/graph/graphCaseTest.cpp index 377056a7..b82deb1e 100644 --- a/test/src/graph/graphCaseTest.cpp +++ b/test/src/graph/graphCaseTest.cpp @@ -415,6 +415,48 @@ TEST_F(GraphCase, NoInputNodesDoNotRequireInput) EXPECT_RGL_SUCCESS(rgl_graph_run(pointsFromArray)); } +TEST_F(GraphCase, ChangingRequiredFieldsBetweenRuns) +{ + spawnCubeOnScene(Mat3x4f::identity()); + + rgl_node_t useRays = nullptr, raytrace = nullptr, compact = nullptr, format = nullptr; + + std::vector> subsequentFormatFields = { + {RGL_FIELD_XYZ_VEC3_F32}, + {RGL_FIELD_XYZ_VEC3_F32, RGL_FIELD_INTENSITY_F32, RGL_FIELD_ENTITY_ID_I32}, + {RGL_FIELD_XYZ_VEC3_F32, RGL_FIELD_INTENSITY_F32}, + {RGL_FIELD_XYZ_VEC3_F32, RGL_FIELD_INTENSITY_F32, RGL_FIELD_DISTANCE_F32, RGL_FIELD_IS_HIT_I32}, + {RGL_FIELD_XYZ_VEC3_F32, RGL_FIELD_DISTANCE_F32}, + }; + + std::vector rays = makeLidar3dRays(360, 180, 0.36, 0.18); + + ASSERT_RGL_SUCCESS(rgl_node_rays_from_mat3x4f(&useRays, rays.data(), rays.size())); + ASSERT_RGL_SUCCESS(rgl_node_raytrace(&raytrace, nullptr)); + ASSERT_RGL_SUCCESS(rgl_node_points_compact(&compact)); + ASSERT_RGL_SUCCESS(rgl_node_points_format(&format, subsequentFormatFields[0].data(), subsequentFormatFields[0].size())); + + ASSERT_RGL_SUCCESS(rgl_graph_node_add_child(useRays, raytrace)); + ASSERT_RGL_SUCCESS(rgl_graph_node_add_child(raytrace, compact)); + ASSERT_RGL_SUCCESS(rgl_graph_node_add_child(compact, format)); + + // 1st method of changing required fields: update node with fields as a parameter + for (auto&& formatFields : subsequentFormatFields) { + ASSERT_RGL_SUCCESS(rgl_node_points_format(&format, formatFields.data(), formatFields.size())); + ASSERT_RGL_SUCCESS(rgl_graph_run(raytrace)); // Run with dirty nodes + ASSERT_RGL_SUCCESS(rgl_graph_run(raytrace)); // Run with valid nodes + } + + // 2nd method of changing required fields: remove child node with user-defined fields requirements + for (auto&& formatFields : subsequentFormatFields) { + ASSERT_RGL_SUCCESS(rgl_node_points_format(&format, formatFields.data(), formatFields.size())); + ASSERT_RGL_SUCCESS(rgl_graph_run(raytrace)); + ASSERT_RGL_SUCCESS(rgl_graph_node_remove_child(compact, format)); // Remove node with extra fields in the pipeline + ASSERT_RGL_SUCCESS(rgl_graph_run(raytrace)); + ASSERT_RGL_SUCCESS(rgl_graph_node_add_child(compact, format)); // Restore connection for the next loop iteration + } +} + // Test for rgl_node_points_visualize. May not work inside docker (graphical environment needed). Uncomment to use. //#if RGL_BUILD_PCL_EXTENSION //#include