diff --git a/crates/build/re_types_builder/src/codegen/cpp/includes.rs b/crates/build/re_types_builder/src/codegen/cpp/includes.rs index a3630364833d..e80ea83d35c6 100644 --- a/crates/build/re_types_builder/src/codegen/cpp/includes.rs +++ b/crates/build/re_types_builder/src/codegen/cpp/includes.rs @@ -89,6 +89,12 @@ impl Includes { self.insert_rerun(&format!("{path}/{typname}.hpp")); } } + + /// Remove all includes that are also in `other`. + pub fn remove_includes(&mut self, other: &Self) { + self.system.retain(|name| !other.system.contains(name)); + self.local.retain(|name| !other.local.contains(name)); + } } impl quote::ToTokens for Includes { diff --git a/crates/build/re_types_builder/src/codegen/cpp/method.rs b/crates/build/re_types_builder/src/codegen/cpp/method.rs index b54beb419654..17b4a1803675 100644 --- a/crates/build/re_types_builder/src/codegen/cpp/method.rs +++ b/crates/build/re_types_builder/src/codegen/cpp/method.rs @@ -83,7 +83,12 @@ impl MethodDocumentation { Self::None => { quote!() } - Self::String(s) => quote_doc_comment(s), + Self::String(s) => { + let lines = s.lines().map(quote_doc_comment); + quote! { + #(#lines)* + } + } Self::Docs(docs) => { let lines = lines_from_docs(reporter, objects, docs); quote_doc_lines(&lines) diff --git a/crates/build/re_types_builder/src/codegen/cpp/mod.rs b/crates/build/re_types_builder/src/codegen/cpp/mod.rs index d8b85f7b371c..ccb03882eb77 100644 --- a/crates/build/re_types_builder/src/codegen/cpp/mod.rs +++ b/crates/build/re_types_builder/src/codegen/cpp/mod.rs @@ -449,7 +449,7 @@ impl QuotedObject { mut hpp_includes: Includes, hpp_type_extensions: &TokenStream, ) -> Self { - let type_ident = obj.ident(); + let archetype_type_ident = obj.ident(); let archetype_name = &obj.fqname; let quoted_docs = quote_obj_docs(reporter, objects, obj); @@ -503,7 +503,7 @@ impl QuotedObject { // Making the constructor explicit prevents all sort of strange errors. // (e.g. `Points3D({{0.0f, 0.0f, 0.0f}})` would previously be ambiguous with the move constructor?!) declaration: MethodDeclaration::constructor(quote! { - explicit #type_ident(#(#parameters),*) : #(#assignments),* + explicit #archetype_type_ident(#(#parameters),*) : #(#assignments),* }), ..Method::default() }); @@ -535,24 +535,24 @@ impl QuotedObject { // update_fields method - this is equivalent to the default constructor. methods.push(Method { - docs: format!("Update only some specific fields of a `{type_ident}`.").into(), + docs: format!("Update only some specific fields of a `{archetype_type_ident}`.").into(), declaration: MethodDeclaration { is_static: true, - return_type: quote!(#type_ident), + return_type: quote!(#archetype_type_ident), name_and_parameters: quote! { update_fields() }, }, definition_body: quote! { - return #type_ident(); + return #archetype_type_ident(); }, inline: true, }); // clear_fields method. methods.push(Method { - docs: format!("Clear all the fields of a `{type_ident}`.").into(), + docs: format!("Clear all the fields of a `{archetype_type_ident}`.").into(), declaration: MethodDeclaration { is_static: true, - return_type: quote!(#type_ident), + return_type: quote!(#archetype_type_ident), name_and_parameters: quote! { clear_fields() }, }, definition_body: { @@ -570,7 +570,7 @@ impl QuotedObject { }); quote! { - auto archetype = #type_ident(); + auto archetype = #archetype_type_ident(); #(#field_assignments)* return archetype; } @@ -591,7 +591,7 @@ impl QuotedObject { docs: obj_field.docs.clone().into(), declaration: MethodDeclaration { is_static: false, - return_type: quote!(#type_ident), + return_type: quote!(#archetype_type_ident), name_and_parameters: quote! { #method_ident(const #field_type& #parameter_ident) && }, @@ -605,6 +605,82 @@ impl QuotedObject { }); } + // columns method that allows partitioning into columns + hpp_includes.insert_rerun("component_column.hpp"); + methods.push(Method { + docs: unindent::unindent("\ + Partitions the component data into multiple sub-batches. + + Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + instead, via `ComponentColumn::from_batch_with_lengths`. + + This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + + The specified `lengths` must sum to the total length of the component batch. + ").into(), + declaration: MethodDeclaration { + is_static: false, + return_type: quote!(Collection), + name_and_parameters: quote! { columns(const Collection& lengths_) }, + }, + definition_body: { + // Plus 1 for the indicator column. + let num_fields = quote_integer(obj.fields.len() + 1); + let push_back_columns = obj.fields.iter().map(|field| { + let field_ident = field_name_ident(field); + quote! { + if (#field_ident.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths( + #field_ident.value(), lengths_ + ).value_or_throw()); + } + } + }); + + quote! { + std::vector columns; + columns.reserve(#num_fields); + #(#push_back_columns)* + columns.push_back( + ComponentColumn::from_indicators<#archetype_type_ident>(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + }, + inline: false, + }); + methods.push(Method { + docs: unindent::unindent( + "Partitions the component data into unit-length sub-batches. + + This is semantically similar to calling `columns` with `std::vector(n, 1)`, + where `n` is automatically guessed.", + ) + .into(), + declaration: MethodDeclaration { + is_static: false, + return_type: quote!(Collection), + name_and_parameters: quote! { columns() }, + }, + definition_body: { + let set_len = obj.fields.iter().map(|field| { + let field_ident = field_name_ident(field); + quote! { + if (#field_ident.has_value()) { + return columns(std::vector(#field_ident.value().length(), 1)); + } + } + }); + + quote! { + #(#set_len)* + return Collection(); + } + }, + inline: false, + }); + let quoted_namespace = if let Some(scope) = obj.scope() { let scope = format_ident!("{}", scope); quote! { #scope::archetypes } @@ -612,15 +688,15 @@ impl QuotedObject { quote! {archetypes} }; - let serialize_method = archetype_serialize(&type_ident, obj, &mut hpp_includes); + let serialize_method = archetype_serialize(&archetype_type_ident, obj, &mut hpp_includes); let serialize_hpp = serialize_method.to_hpp_tokens(reporter, objects); - let serialize_cpp = - serialize_method.to_cpp_tokens("e!(AsComponents<#quoted_namespace::#type_ident>)); + let serialize_cpp = serialize_method + .to_cpp_tokens("e!(AsComponents<#quoted_namespace::#archetype_type_ident>)); let methods_hpp = methods.iter().map(|m| m.to_hpp_tokens(reporter, objects)); let methods_cpp = methods .iter() - .map(|m| m.to_cpp_tokens("e!(#type_ident))); + .map(|m| m.to_cpp_tokens("e!(#archetype_type_ident))); let indicator_comment = quote_doc_comment("Indicator component, used to identify the archetype when converting to a list of components."); let indicator_component_fqname = @@ -648,9 +724,12 @@ impl QuotedObject { let default_ctor = if obj.is_attr_set(ATTR_CPP_NO_DEFAULT_CTOR) { quote! {} } else { - quote! { #type_ident() = default; } + quote! { #archetype_type_ident() = default; } }; + // Don't add any includes that are already in the hpp anyways. + cpp_includes.remove_includes(&hpp_includes); + // Note that we run into "rule of five": https://en.cppreference.com/w/cpp/language/rule_of_three // * we have to manually opt-in to default ctor because we (most of the time) have a user defined constructor // -> this means that there's no non-move constructors/assignments @@ -664,7 +743,7 @@ impl QuotedObject { namespace rerun::#quoted_namespace { #quoted_docs - struct #deprecation_notice #type_ident { + struct #deprecation_notice #archetype_type_ident { #(#field_declarations;)* public: @@ -685,10 +764,10 @@ impl QuotedObject { public: #default_ctor - #type_ident(#type_ident&& other) = default; - #type_ident(const #type_ident& other) = default; - #type_ident& operator=(const #type_ident& other) = default; - #type_ident& operator=(#type_ident&& other) = default; + #archetype_type_ident(#archetype_type_ident&& other) = default; + #archetype_type_ident(const #archetype_type_ident& other) = default; + #archetype_type_ident& operator=(const #archetype_type_ident& other) = default; + #archetype_type_ident& operator=(#archetype_type_ident&& other) = default; #NEWLINE_TOKEN #NEWLINE_TOKEN @@ -708,7 +787,7 @@ impl QuotedObject { #doc_hide_comment template<> - struct AsComponents<#quoted_namespace::#type_ident> { + struct AsComponents<#quoted_namespace::#archetype_type_ident> { #serialize_hpp }; } diff --git a/docs/snippets/all/archetypes/points3d_send_columns.cpp b/docs/snippets/all/archetypes/points3d_send_columns.cpp index 72b57ac72132..bf5e73ca5d24 100644 --- a/docs/snippets/all/archetypes/points3d_send_columns.cpp +++ b/docs/snippets/all/archetypes/points3d_send_columns.cpp @@ -29,28 +29,11 @@ int main() { auto times = rerun::Collection{10s, 11s, 12s, 13s, 14s}; auto time_column = rerun::TimeColumn::from_times("time", std::move(times)); - // Interpret raw positions and color data as rerun components and partition them. - auto indicator_batch = rerun::ComponentColumn::from_indicators(5); - auto position_batch = rerun::ComponentColumn::from_loggable_with_lengths( - rerun::Collection(std::move(positions)), - {2, 4, 4, 3, 4} - ); - auto color_batch = rerun::ComponentColumn::from_loggable( - rerun::Collection(std::move(colors)) - ); - auto radius_batch = rerun::ComponentColumn::from_loggable( - rerun::Collection(std::move(radii)) - ); - - // TODO(#8754) : use tagged columnar APIs - rec.send_columns( - "points", - time_column, - { - indicator_batch.value_or_throw(), - position_batch.value_or_throw(), - color_batch.value_or_throw(), - radius_batch.value_or_throw(), - } - ); + // Partition our data as expected across the 5 timesteps. + auto position = + rerun::Points3D::update_fields().with_positions(positions).columns({2, 4, 4, 3, 4}); + auto color_and_radius = + rerun::Points3D::update_fields().with_colors(colors).with_radii(radii).columns(); + + rec.send_columns2("points", time_column, position, color_and_radius); } diff --git a/docs/snippets/snippets.toml b/docs/snippets/snippets.toml index 542c7683794a..e438c4a099dd 100644 --- a/docs/snippets/snippets.toml +++ b/docs/snippets/snippets.toml @@ -102,10 +102,10 @@ "rust", # Missing examples ] "howto/any_batch_value_send_columns" = [ - "cpp", # Not implemented + "cpp", # Not implemented ] "howto/any_values_send_columns" = [ - "cpp", # Not implemented + "cpp", # Not implemented ] "migration/log_line" = [ # Not a complete example -- just a single log line "cpp", @@ -236,9 +236,6 @@ quick_start = [ # These examples don't have exactly the same implementation. "py", "rust", ] -"archetypes/points3d_send_columns" = [ - "cpp", # TODO(#8754): needs tagged columnar APIs -] "archetypes/points3d_random" = [ # TODO(#3206): examples use different RNGs "cpp", "py", diff --git a/rerun_cpp/src/rerun/archetypes/annotation_context.cpp b/rerun_cpp/src/rerun/archetypes/annotation_context.cpp index 2eedd044bdca..1d6ac8024287 100644 --- a/rerun_cpp/src/rerun/archetypes/annotation_context.cpp +++ b/rerun_cpp/src/rerun/archetypes/annotation_context.cpp @@ -13,6 +13,28 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection AnnotationContext::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(2); + if (context.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(context.value(), lengths_).value_or_throw() + ); + } + columns.push_back(ComponentColumn::from_indicators( + static_cast(lengths_.size()) + ) + .value_or_throw()); + return columns; + } + + Collection AnnotationContext::columns() { + if (context.has_value()) { + return columns(std::vector(context.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/annotation_context.hpp b/rerun_cpp/src/rerun/archetypes/annotation_context.hpp index 4d42cf673a6b..1575cdb75ec2 100644 --- a/rerun_cpp/src/rerun/archetypes/annotation_context.hpp +++ b/rerun_cpp/src/rerun/archetypes/annotation_context.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/annotation_context.hpp" #include "../indicator_component.hpp" #include "../result.hpp" @@ -106,6 +107,22 @@ namespace rerun::archetypes { context = ComponentBatch::from_loggable(_context, Descriptor_context).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/arrows2d.cpp b/rerun_cpp/src/rerun/archetypes/arrows2d.cpp index bc6242122d37..c38ea2e8f1ec 100644 --- a/rerun_cpp/src/rerun/archetypes/arrows2d.cpp +++ b/rerun_cpp/src/rerun/archetypes/arrows2d.cpp @@ -29,6 +29,83 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection Arrows2D::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(9); + if (vectors.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(vectors.value(), lengths_).value_or_throw() + ); + } + if (origins.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(origins.value(), lengths_).value_or_throw() + ); + } + if (radii.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(radii.value(), lengths_).value_or_throw() + ); + } + if (colors.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(colors.value(), lengths_).value_or_throw() + ); + } + if (labels.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(labels.value(), lengths_).value_or_throw() + ); + } + if (show_labels.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(show_labels.value(), lengths_) + .value_or_throw() + ); + } + if (draw_order.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(draw_order.value(), lengths_) + .value_or_throw()); + } + if (class_ids.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(class_ids.value(), lengths_) + .value_or_throw()); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection Arrows2D::columns() { + if (vectors.has_value()) { + return columns(std::vector(vectors.value().length(), 1)); + } + if (origins.has_value()) { + return columns(std::vector(origins.value().length(), 1)); + } + if (radii.has_value()) { + return columns(std::vector(radii.value().length(), 1)); + } + if (colors.has_value()) { + return columns(std::vector(colors.value().length(), 1)); + } + if (labels.has_value()) { + return columns(std::vector(labels.value().length(), 1)); + } + if (show_labels.has_value()) { + return columns(std::vector(show_labels.value().length(), 1)); + } + if (draw_order.has_value()) { + return columns(std::vector(draw_order.value().length(), 1)); + } + if (class_ids.has_value()) { + return columns(std::vector(class_ids.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/arrows2d.hpp b/rerun_cpp/src/rerun/archetypes/arrows2d.hpp index 1bf583ecdfe0..b4b24f0dac80 100644 --- a/rerun_cpp/src/rerun/archetypes/arrows2d.hpp +++ b/rerun_cpp/src/rerun/archetypes/arrows2d.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/class_id.hpp" #include "../components/color.hpp" #include "../components/draw_order.hpp" @@ -214,6 +215,22 @@ namespace rerun::archetypes { ComponentBatch::from_loggable(_class_ids, Descriptor_class_ids).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/arrows3d.cpp b/rerun_cpp/src/rerun/archetypes/arrows3d.cpp index dbf8999cef1d..600136ee75db 100644 --- a/rerun_cpp/src/rerun/archetypes/arrows3d.cpp +++ b/rerun_cpp/src/rerun/archetypes/arrows3d.cpp @@ -26,6 +26,76 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection Arrows3D::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(8); + if (vectors.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(vectors.value(), lengths_).value_or_throw() + ); + } + if (origins.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(origins.value(), lengths_).value_or_throw() + ); + } + if (radii.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(radii.value(), lengths_).value_or_throw() + ); + } + if (colors.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(colors.value(), lengths_).value_or_throw() + ); + } + if (labels.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(labels.value(), lengths_).value_or_throw() + ); + } + if (show_labels.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(show_labels.value(), lengths_) + .value_or_throw() + ); + } + if (class_ids.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(class_ids.value(), lengths_) + .value_or_throw()); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection Arrows3D::columns() { + if (vectors.has_value()) { + return columns(std::vector(vectors.value().length(), 1)); + } + if (origins.has_value()) { + return columns(std::vector(origins.value().length(), 1)); + } + if (radii.has_value()) { + return columns(std::vector(radii.value().length(), 1)); + } + if (colors.has_value()) { + return columns(std::vector(colors.value().length(), 1)); + } + if (labels.has_value()) { + return columns(std::vector(labels.value().length(), 1)); + } + if (show_labels.has_value()) { + return columns(std::vector(show_labels.value().length(), 1)); + } + if (class_ids.has_value()) { + return columns(std::vector(class_ids.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/arrows3d.hpp b/rerun_cpp/src/rerun/archetypes/arrows3d.hpp index 046b078bc5d5..a3d8246bb6da 100644 --- a/rerun_cpp/src/rerun/archetypes/arrows3d.hpp +++ b/rerun_cpp/src/rerun/archetypes/arrows3d.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/class_id.hpp" #include "../components/color.hpp" #include "../components/position3d.hpp" @@ -211,6 +212,22 @@ namespace rerun::archetypes { ComponentBatch::from_loggable(_class_ids, Descriptor_class_ids).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/asset3d.cpp b/rerun_cpp/src/rerun/archetypes/asset3d.cpp index d5eb049084c1..490da9ffb365 100644 --- a/rerun_cpp/src/rerun/archetypes/asset3d.cpp +++ b/rerun_cpp/src/rerun/archetypes/asset3d.cpp @@ -18,6 +18,44 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection Asset3D::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(4); + if (blob.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(blob.value(), lengths_).value_or_throw() + ); + } + if (media_type.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(media_type.value(), lengths_) + .value_or_throw()); + } + if (albedo_factor.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(albedo_factor.value(), lengths_) + .value_or_throw() + ); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection Asset3D::columns() { + if (blob.has_value()) { + return columns(std::vector(blob.value().length(), 1)); + } + if (media_type.has_value()) { + return columns(std::vector(media_type.value().length(), 1)); + } + if (albedo_factor.has_value()) { + return columns(std::vector(albedo_factor.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/asset3d.hpp b/rerun_cpp/src/rerun/archetypes/asset3d.hpp index dd56ca28522f..d8cde2391e27 100644 --- a/rerun_cpp/src/rerun/archetypes/asset3d.hpp +++ b/rerun_cpp/src/rerun/archetypes/asset3d.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/albedo_factor.hpp" #include "../components/blob.hpp" #include "../components/media_type.hpp" @@ -172,6 +173,22 @@ namespace rerun::archetypes { .value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/asset_video.cpp b/rerun_cpp/src/rerun/archetypes/asset_video.cpp index 41f646a1a445..8f1f635099e5 100644 --- a/rerun_cpp/src/rerun/archetypes/asset_video.cpp +++ b/rerun_cpp/src/rerun/archetypes/asset_video.cpp @@ -15,6 +15,35 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection AssetVideo::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(3); + if (blob.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(blob.value(), lengths_).value_or_throw() + ); + } + if (media_type.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(media_type.value(), lengths_) + .value_or_throw()); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection AssetVideo::columns() { + if (blob.has_value()) { + return columns(std::vector(blob.value().length(), 1)); + } + if (media_type.has_value()) { + return columns(std::vector(media_type.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/asset_video.hpp b/rerun_cpp/src/rerun/archetypes/asset_video.hpp index d1dbc3725d07..bd62127702d3 100644 --- a/rerun_cpp/src/rerun/archetypes/asset_video.hpp +++ b/rerun_cpp/src/rerun/archetypes/asset_video.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/blob.hpp" #include "../components/media_type.hpp" #include "../indicator_component.hpp" @@ -215,6 +216,22 @@ namespace rerun::archetypes { ComponentBatch::from_loggable(_media_type, Descriptor_media_type).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/bar_chart.cpp b/rerun_cpp/src/rerun/archetypes/bar_chart.cpp index 30de6ff7d6a4..d3a4df04c78e 100644 --- a/rerun_cpp/src/rerun/archetypes/bar_chart.cpp +++ b/rerun_cpp/src/rerun/archetypes/bar_chart.cpp @@ -14,6 +14,36 @@ namespace rerun::archetypes { ComponentBatch::empty(Descriptor_color).value_or_throw(); return archetype; } + + Collection BarChart::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(3); + if (values.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(values.value(), lengths_).value_or_throw() + ); + } + if (color.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(color.value(), lengths_).value_or_throw() + ); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection BarChart::columns() { + if (values.has_value()) { + return columns(std::vector(values.value().length(), 1)); + } + if (color.has_value()) { + return columns(std::vector(color.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/bar_chart.hpp b/rerun_cpp/src/rerun/archetypes/bar_chart.hpp index 183769acb8f4..50eb559decc0 100644 --- a/rerun_cpp/src/rerun/archetypes/bar_chart.hpp +++ b/rerun_cpp/src/rerun/archetypes/bar_chart.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/color.hpp" #include "../components/tensor_data.hpp" #include "../indicator_component.hpp" @@ -208,6 +209,22 @@ namespace rerun::archetypes { color = ComponentBatch::from_loggable(_color, Descriptor_color).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/boxes2d.cpp b/rerun_cpp/src/rerun/archetypes/boxes2d.cpp index d5054d3ff2d6..5e1c9789d075 100644 --- a/rerun_cpp/src/rerun/archetypes/boxes2d.cpp +++ b/rerun_cpp/src/rerun/archetypes/boxes2d.cpp @@ -30,6 +30,82 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection Boxes2D::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(9); + if (half_sizes.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(half_sizes.value(), lengths_) + .value_or_throw()); + } + if (centers.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(centers.value(), lengths_).value_or_throw() + ); + } + if (colors.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(colors.value(), lengths_).value_or_throw() + ); + } + if (radii.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(radii.value(), lengths_).value_or_throw() + ); + } + if (labels.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(labels.value(), lengths_).value_or_throw() + ); + } + if (show_labels.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(show_labels.value(), lengths_) + .value_or_throw() + ); + } + if (draw_order.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(draw_order.value(), lengths_) + .value_or_throw()); + } + if (class_ids.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(class_ids.value(), lengths_) + .value_or_throw()); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection Boxes2D::columns() { + if (half_sizes.has_value()) { + return columns(std::vector(half_sizes.value().length(), 1)); + } + if (centers.has_value()) { + return columns(std::vector(centers.value().length(), 1)); + } + if (colors.has_value()) { + return columns(std::vector(colors.value().length(), 1)); + } + if (radii.has_value()) { + return columns(std::vector(radii.value().length(), 1)); + } + if (labels.has_value()) { + return columns(std::vector(labels.value().length(), 1)); + } + if (show_labels.has_value()) { + return columns(std::vector(show_labels.value().length(), 1)); + } + if (draw_order.has_value()) { + return columns(std::vector(draw_order.value().length(), 1)); + } + if (class_ids.has_value()) { + return columns(std::vector(class_ids.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/boxes2d.hpp b/rerun_cpp/src/rerun/archetypes/boxes2d.hpp index ced5cd2a00b6..c2e48b460cfe 100644 --- a/rerun_cpp/src/rerun/archetypes/boxes2d.hpp +++ b/rerun_cpp/src/rerun/archetypes/boxes2d.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/class_id.hpp" #include "../components/color.hpp" #include "../components/draw_order.hpp" @@ -238,6 +239,22 @@ namespace rerun::archetypes { ComponentBatch::from_loggable(_class_ids, Descriptor_class_ids).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/boxes3d.cpp b/rerun_cpp/src/rerun/archetypes/boxes3d.cpp index 74de853773a6..77d527268152 100644 --- a/rerun_cpp/src/rerun/archetypes/boxes3d.cpp +++ b/rerun_cpp/src/rerun/archetypes/boxes3d.cpp @@ -39,6 +39,100 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection Boxes3D::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(11); + if (half_sizes.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(half_sizes.value(), lengths_) + .value_or_throw()); + } + if (centers.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(centers.value(), lengths_).value_or_throw() + ); + } + if (rotation_axis_angles.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(rotation_axis_angles.value(), lengths_) + .value_or_throw() + ); + } + if (quaternions.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(quaternions.value(), lengths_) + .value_or_throw() + ); + } + if (colors.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(colors.value(), lengths_).value_or_throw() + ); + } + if (radii.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(radii.value(), lengths_).value_or_throw() + ); + } + if (fill_mode.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fill_mode.value(), lengths_) + .value_or_throw()); + } + if (labels.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(labels.value(), lengths_).value_or_throw() + ); + } + if (show_labels.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(show_labels.value(), lengths_) + .value_or_throw() + ); + } + if (class_ids.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(class_ids.value(), lengths_) + .value_or_throw()); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection Boxes3D::columns() { + if (half_sizes.has_value()) { + return columns(std::vector(half_sizes.value().length(), 1)); + } + if (centers.has_value()) { + return columns(std::vector(centers.value().length(), 1)); + } + if (rotation_axis_angles.has_value()) { + return columns(std::vector(rotation_axis_angles.value().length(), 1)); + } + if (quaternions.has_value()) { + return columns(std::vector(quaternions.value().length(), 1)); + } + if (colors.has_value()) { + return columns(std::vector(colors.value().length(), 1)); + } + if (radii.has_value()) { + return columns(std::vector(radii.value().length(), 1)); + } + if (fill_mode.has_value()) { + return columns(std::vector(fill_mode.value().length(), 1)); + } + if (labels.has_value()) { + return columns(std::vector(labels.value().length(), 1)); + } + if (show_labels.has_value()) { + return columns(std::vector(show_labels.value().length(), 1)); + } + if (class_ids.has_value()) { + return columns(std::vector(class_ids.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/boxes3d.hpp b/rerun_cpp/src/rerun/archetypes/boxes3d.hpp index 5b46d4b1ee69..1d9ceca3f7b2 100644 --- a/rerun_cpp/src/rerun/archetypes/boxes3d.hpp +++ b/rerun_cpp/src/rerun/archetypes/boxes3d.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/class_id.hpp" #include "../components/color.hpp" #include "../components/fill_mode.hpp" @@ -313,6 +314,22 @@ namespace rerun::archetypes { ComponentBatch::from_loggable(_class_ids, Descriptor_class_ids).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/capsules3d.cpp b/rerun_cpp/src/rerun/archetypes/capsules3d.cpp index 26f2e542fa11..dfd56f22f040 100644 --- a/rerun_cpp/src/rerun/archetypes/capsules3d.cpp +++ b/rerun_cpp/src/rerun/archetypes/capsules3d.cpp @@ -35,6 +35,95 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection Capsules3D::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(10); + if (lengths.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(lengths.value(), lengths_).value_or_throw() + ); + } + if (radii.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(radii.value(), lengths_).value_or_throw() + ); + } + if (translations.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(translations.value(), lengths_) + .value_or_throw() + ); + } + if (rotation_axis_angles.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(rotation_axis_angles.value(), lengths_) + .value_or_throw() + ); + } + if (quaternions.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(quaternions.value(), lengths_) + .value_or_throw() + ); + } + if (colors.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(colors.value(), lengths_).value_or_throw() + ); + } + if (labels.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(labels.value(), lengths_).value_or_throw() + ); + } + if (show_labels.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(show_labels.value(), lengths_) + .value_or_throw() + ); + } + if (class_ids.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(class_ids.value(), lengths_) + .value_or_throw()); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection Capsules3D::columns() { + if (lengths.has_value()) { + return columns(std::vector(lengths.value().length(), 1)); + } + if (radii.has_value()) { + return columns(std::vector(radii.value().length(), 1)); + } + if (translations.has_value()) { + return columns(std::vector(translations.value().length(), 1)); + } + if (rotation_axis_angles.has_value()) { + return columns(std::vector(rotation_axis_angles.value().length(), 1)); + } + if (quaternions.has_value()) { + return columns(std::vector(quaternions.value().length(), 1)); + } + if (colors.has_value()) { + return columns(std::vector(colors.value().length(), 1)); + } + if (labels.has_value()) { + return columns(std::vector(labels.value().length(), 1)); + } + if (show_labels.has_value()) { + return columns(std::vector(show_labels.value().length(), 1)); + } + if (class_ids.has_value()) { + return columns(std::vector(class_ids.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/capsules3d.hpp b/rerun_cpp/src/rerun/archetypes/capsules3d.hpp index 70864fd15188..3f9162203542 100644 --- a/rerun_cpp/src/rerun/archetypes/capsules3d.hpp +++ b/rerun_cpp/src/rerun/archetypes/capsules3d.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/class_id.hpp" #include "../components/color.hpp" #include "../components/length.hpp" @@ -285,6 +286,22 @@ namespace rerun::archetypes { ComponentBatch::from_loggable(_class_ids, Descriptor_class_ids).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/clear.cpp b/rerun_cpp/src/rerun/archetypes/clear.cpp index d707b4a62ff7..76748ed833ec 100644 --- a/rerun_cpp/src/rerun/archetypes/clear.cpp +++ b/rerun_cpp/src/rerun/archetypes/clear.cpp @@ -13,6 +13,29 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection Clear::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(2); + if (is_recursive.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(is_recursive.value(), lengths_) + .value_or_throw() + ); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection Clear::columns() { + if (is_recursive.has_value()) { + return columns(std::vector(is_recursive.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/clear.hpp b/rerun_cpp/src/rerun/archetypes/clear.hpp index c11e5214e46e..613e3f5f64d3 100644 --- a/rerun_cpp/src/rerun/archetypes/clear.hpp +++ b/rerun_cpp/src/rerun/archetypes/clear.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/clear_is_recursive.hpp" #include "../indicator_component.hpp" #include "../rerun_sdk_export.hpp" @@ -133,6 +134,22 @@ namespace rerun::archetypes { .value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/depth_image.cpp b/rerun_cpp/src/rerun/archetypes/depth_image.cpp index 1335989a0ed2..1819b3941737 100644 --- a/rerun_cpp/src/rerun/archetypes/depth_image.cpp +++ b/rerun_cpp/src/rerun/archetypes/depth_image.cpp @@ -27,6 +27,76 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection DepthImage::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(8); + if (buffer.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(buffer.value(), lengths_).value_or_throw() + ); + } + if (format.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(format.value(), lengths_).value_or_throw() + ); + } + if (meter.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(meter.value(), lengths_).value_or_throw() + ); + } + if (colormap.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(colormap.value(), lengths_) + .value_or_throw()); + } + if (depth_range.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(depth_range.value(), lengths_) + .value_or_throw() + ); + } + if (point_fill_ratio.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(point_fill_ratio.value(), lengths_) + .value_or_throw() + ); + } + if (draw_order.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(draw_order.value(), lengths_) + .value_or_throw()); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection DepthImage::columns() { + if (buffer.has_value()) { + return columns(std::vector(buffer.value().length(), 1)); + } + if (format.has_value()) { + return columns(std::vector(format.value().length(), 1)); + } + if (meter.has_value()) { + return columns(std::vector(meter.value().length(), 1)); + } + if (colormap.has_value()) { + return columns(std::vector(colormap.value().length(), 1)); + } + if (depth_range.has_value()) { + return columns(std::vector(depth_range.value().length(), 1)); + } + if (point_fill_ratio.has_value()) { + return columns(std::vector(point_fill_ratio.value().length(), 1)); + } + if (draw_order.has_value()) { + return columns(std::vector(draw_order.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/depth_image.hpp b/rerun_cpp/src/rerun/archetypes/depth_image.hpp index 98d595c56ac0..f1505405d8c4 100644 --- a/rerun_cpp/src/rerun/archetypes/depth_image.hpp +++ b/rerun_cpp/src/rerun/archetypes/depth_image.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/colormap.hpp" #include "../components/depth_meter.hpp" #include "../components/draw_order.hpp" @@ -314,6 +315,22 @@ namespace rerun::archetypes { ComponentBatch::from_loggable(_draw_order, Descriptor_draw_order).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/ellipsoids3d.cpp b/rerun_cpp/src/rerun/archetypes/ellipsoids3d.cpp index 27b9988ba39c..995881f41097 100644 --- a/rerun_cpp/src/rerun/archetypes/ellipsoids3d.cpp +++ b/rerun_cpp/src/rerun/archetypes/ellipsoids3d.cpp @@ -40,6 +40,99 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection Ellipsoids3D::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(11); + if (half_sizes.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(half_sizes.value(), lengths_) + .value_or_throw()); + } + if (centers.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(centers.value(), lengths_).value_or_throw() + ); + } + if (rotation_axis_angles.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(rotation_axis_angles.value(), lengths_) + .value_or_throw() + ); + } + if (quaternions.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(quaternions.value(), lengths_) + .value_or_throw() + ); + } + if (colors.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(colors.value(), lengths_).value_or_throw() + ); + } + if (line_radii.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(line_radii.value(), lengths_) + .value_or_throw()); + } + if (fill_mode.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fill_mode.value(), lengths_) + .value_or_throw()); + } + if (labels.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(labels.value(), lengths_).value_or_throw() + ); + } + if (show_labels.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(show_labels.value(), lengths_) + .value_or_throw() + ); + } + if (class_ids.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(class_ids.value(), lengths_) + .value_or_throw()); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection Ellipsoids3D::columns() { + if (half_sizes.has_value()) { + return columns(std::vector(half_sizes.value().length(), 1)); + } + if (centers.has_value()) { + return columns(std::vector(centers.value().length(), 1)); + } + if (rotation_axis_angles.has_value()) { + return columns(std::vector(rotation_axis_angles.value().length(), 1)); + } + if (quaternions.has_value()) { + return columns(std::vector(quaternions.value().length(), 1)); + } + if (colors.has_value()) { + return columns(std::vector(colors.value().length(), 1)); + } + if (line_radii.has_value()) { + return columns(std::vector(line_radii.value().length(), 1)); + } + if (fill_mode.has_value()) { + return columns(std::vector(fill_mode.value().length(), 1)); + } + if (labels.has_value()) { + return columns(std::vector(labels.value().length(), 1)); + } + if (show_labels.has_value()) { + return columns(std::vector(show_labels.value().length(), 1)); + } + if (class_ids.has_value()) { + return columns(std::vector(class_ids.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/ellipsoids3d.hpp b/rerun_cpp/src/rerun/archetypes/ellipsoids3d.hpp index efc9c5f60e33..ba61754a59e5 100644 --- a/rerun_cpp/src/rerun/archetypes/ellipsoids3d.hpp +++ b/rerun_cpp/src/rerun/archetypes/ellipsoids3d.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/class_id.hpp" #include "../components/color.hpp" #include "../components/fill_mode.hpp" @@ -324,6 +325,22 @@ namespace rerun::archetypes { ComponentBatch::from_loggable(_class_ids, Descriptor_class_ids).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/encoded_image.cpp b/rerun_cpp/src/rerun/archetypes/encoded_image.cpp index 262846403c87..ee294035a5c7 100644 --- a/rerun_cpp/src/rerun/archetypes/encoded_image.cpp +++ b/rerun_cpp/src/rerun/archetypes/encoded_image.cpp @@ -20,6 +20,50 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection EncodedImage::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(5); + if (blob.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(blob.value(), lengths_).value_or_throw() + ); + } + if (media_type.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(media_type.value(), lengths_) + .value_or_throw()); + } + if (opacity.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(opacity.value(), lengths_).value_or_throw() + ); + } + if (draw_order.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(draw_order.value(), lengths_) + .value_or_throw()); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection EncodedImage::columns() { + if (blob.has_value()) { + return columns(std::vector(blob.value().length(), 1)); + } + if (media_type.has_value()) { + return columns(std::vector(media_type.value().length(), 1)); + } + if (opacity.has_value()) { + return columns(std::vector(opacity.value().length(), 1)); + } + if (draw_order.has_value()) { + return columns(std::vector(draw_order.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/encoded_image.hpp b/rerun_cpp/src/rerun/archetypes/encoded_image.hpp index 7364c19679a9..d9a551a2a47d 100644 --- a/rerun_cpp/src/rerun/archetypes/encoded_image.hpp +++ b/rerun_cpp/src/rerun/archetypes/encoded_image.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/blob.hpp" #include "../components/draw_order.hpp" #include "../components/media_type.hpp" @@ -171,6 +172,22 @@ namespace rerun::archetypes { ComponentBatch::from_loggable(_draw_order, Descriptor_draw_order).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/geo_line_strings.cpp b/rerun_cpp/src/rerun/archetypes/geo_line_strings.cpp index e53680d0176b..dcb2cfc34a61 100644 --- a/rerun_cpp/src/rerun/archetypes/geo_line_strings.cpp +++ b/rerun_cpp/src/rerun/archetypes/geo_line_strings.cpp @@ -17,6 +17,45 @@ namespace rerun::archetypes { ComponentBatch::empty(Descriptor_colors).value_or_throw(); return archetype; } + + Collection GeoLineStrings::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(4); + if (line_strings.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(line_strings.value(), lengths_) + .value_or_throw() + ); + } + if (radii.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(radii.value(), lengths_).value_or_throw() + ); + } + if (colors.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(colors.value(), lengths_).value_or_throw() + ); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection GeoLineStrings::columns() { + if (line_strings.has_value()) { + return columns(std::vector(line_strings.value().length(), 1)); + } + if (radii.has_value()) { + return columns(std::vector(radii.value().length(), 1)); + } + if (colors.has_value()) { + return columns(std::vector(colors.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/geo_line_strings.hpp b/rerun_cpp/src/rerun/archetypes/geo_line_strings.hpp index bd71dee6e1ad..d7b6e1ab97cf 100644 --- a/rerun_cpp/src/rerun/archetypes/geo_line_strings.hpp +++ b/rerun_cpp/src/rerun/archetypes/geo_line_strings.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/color.hpp" #include "../components/geo_line_string.hpp" #include "../components/radius.hpp" @@ -129,6 +130,22 @@ namespace rerun::archetypes { colors = ComponentBatch::from_loggable(_colors, Descriptor_colors).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/geo_points.cpp b/rerun_cpp/src/rerun/archetypes/geo_points.cpp index ae291d97758b..e12e2a6bef58 100644 --- a/rerun_cpp/src/rerun/archetypes/geo_points.cpp +++ b/rerun_cpp/src/rerun/archetypes/geo_points.cpp @@ -19,6 +19,50 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection GeoPoints::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(5); + if (positions.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(positions.value(), lengths_) + .value_or_throw()); + } + if (radii.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(radii.value(), lengths_).value_or_throw() + ); + } + if (colors.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(colors.value(), lengths_).value_or_throw() + ); + } + if (class_ids.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(class_ids.value(), lengths_) + .value_or_throw()); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection GeoPoints::columns() { + if (positions.has_value()) { + return columns(std::vector(positions.value().length(), 1)); + } + if (radii.has_value()) { + return columns(std::vector(radii.value().length(), 1)); + } + if (colors.has_value()) { + return columns(std::vector(colors.value().length(), 1)); + } + if (class_ids.has_value()) { + return columns(std::vector(class_ids.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/geo_points.hpp b/rerun_cpp/src/rerun/archetypes/geo_points.hpp index 432ce21c6d20..4a14a05599bb 100644 --- a/rerun_cpp/src/rerun/archetypes/geo_points.hpp +++ b/rerun_cpp/src/rerun/archetypes/geo_points.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/class_id.hpp" #include "../components/color.hpp" #include "../components/lat_lon.hpp" @@ -141,6 +142,22 @@ namespace rerun::archetypes { ComponentBatch::from_loggable(_class_ids, Descriptor_class_ids).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/graph_edges.cpp b/rerun_cpp/src/rerun/archetypes/graph_edges.cpp index b4a17fd8d664..81085ab365eb 100644 --- a/rerun_cpp/src/rerun/archetypes/graph_edges.cpp +++ b/rerun_cpp/src/rerun/archetypes/graph_edges.cpp @@ -15,6 +15,35 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection GraphEdges::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(3); + if (edges.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(edges.value(), lengths_).value_or_throw() + ); + } + if (graph_type.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(graph_type.value(), lengths_) + .value_or_throw()); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection GraphEdges::columns() { + if (edges.has_value()) { + return columns(std::vector(edges.value().length(), 1)); + } + if (graph_type.has_value()) { + return columns(std::vector(graph_type.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/graph_edges.hpp b/rerun_cpp/src/rerun/archetypes/graph_edges.hpp index 4e7c1a0daa70..c0fe9bab70a5 100644 --- a/rerun_cpp/src/rerun/archetypes/graph_edges.hpp +++ b/rerun_cpp/src/rerun/archetypes/graph_edges.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/graph_edge.hpp" #include "../components/graph_type.hpp" #include "../indicator_component.hpp" @@ -105,6 +106,22 @@ namespace rerun::archetypes { ComponentBatch::from_loggable(_graph_type, Descriptor_graph_type).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/graph_nodes.cpp b/rerun_cpp/src/rerun/archetypes/graph_nodes.cpp index 1cf06836371e..b8da1b853aae 100644 --- a/rerun_cpp/src/rerun/archetypes/graph_nodes.cpp +++ b/rerun_cpp/src/rerun/archetypes/graph_nodes.cpp @@ -25,6 +25,67 @@ namespace rerun::archetypes { ComponentBatch::empty(Descriptor_radii).value_or_throw(); return archetype; } + + Collection GraphNodes::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(7); + if (node_ids.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(node_ids.value(), lengths_) + .value_or_throw()); + } + if (positions.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(positions.value(), lengths_) + .value_or_throw()); + } + if (colors.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(colors.value(), lengths_).value_or_throw() + ); + } + if (labels.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(labels.value(), lengths_).value_or_throw() + ); + } + if (show_labels.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(show_labels.value(), lengths_) + .value_or_throw() + ); + } + if (radii.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(radii.value(), lengths_).value_or_throw() + ); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection GraphNodes::columns() { + if (node_ids.has_value()) { + return columns(std::vector(node_ids.value().length(), 1)); + } + if (positions.has_value()) { + return columns(std::vector(positions.value().length(), 1)); + } + if (colors.has_value()) { + return columns(std::vector(colors.value().length(), 1)); + } + if (labels.has_value()) { + return columns(std::vector(labels.value().length(), 1)); + } + if (show_labels.has_value()) { + return columns(std::vector(show_labels.value().length(), 1)); + } + if (radii.has_value()) { + return columns(std::vector(radii.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/graph_nodes.hpp b/rerun_cpp/src/rerun/archetypes/graph_nodes.hpp index f154e8bf7337..0fefb168ca1b 100644 --- a/rerun_cpp/src/rerun/archetypes/graph_nodes.hpp +++ b/rerun_cpp/src/rerun/archetypes/graph_nodes.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/color.hpp" #include "../components/graph_node.hpp" #include "../components/position2d.hpp" @@ -158,6 +159,22 @@ namespace rerun::archetypes { radii = ComponentBatch::from_loggable(_radii, Descriptor_radii).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/image.cpp b/rerun_cpp/src/rerun/archetypes/image.cpp index 2c7e053bcf36..b4a959e592cd 100644 --- a/rerun_cpp/src/rerun/archetypes/image.cpp +++ b/rerun_cpp/src/rerun/archetypes/image.cpp @@ -19,6 +19,51 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection Image::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(5); + if (buffer.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(buffer.value(), lengths_).value_or_throw() + ); + } + if (format.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(format.value(), lengths_).value_or_throw() + ); + } + if (opacity.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(opacity.value(), lengths_).value_or_throw() + ); + } + if (draw_order.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(draw_order.value(), lengths_) + .value_or_throw()); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection Image::columns() { + if (buffer.has_value()) { + return columns(std::vector(buffer.value().length(), 1)); + } + if (format.has_value()) { + return columns(std::vector(format.value().length(), 1)); + } + if (opacity.has_value()) { + return columns(std::vector(opacity.value().length(), 1)); + } + if (draw_order.has_value()) { + return columns(std::vector(draw_order.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/image.hpp b/rerun_cpp/src/rerun/archetypes/image.hpp index d36818c6f3cb..3706095bc0b5 100644 --- a/rerun_cpp/src/rerun/archetypes/image.hpp +++ b/rerun_cpp/src/rerun/archetypes/image.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/draw_order.hpp" #include "../components/image_buffer.hpp" #include "../components/image_format.hpp" @@ -360,6 +361,22 @@ namespace rerun::archetypes { ComponentBatch::from_loggable(_draw_order, Descriptor_draw_order).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/instance_poses3d.cpp b/rerun_cpp/src/rerun/archetypes/instance_poses3d.cpp index 15d2205350ee..49342877e5c5 100644 --- a/rerun_cpp/src/rerun/archetypes/instance_poses3d.cpp +++ b/rerun_cpp/src/rerun/archetypes/instance_poses3d.cpp @@ -26,6 +26,63 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection InstancePoses3D::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(6); + if (translations.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(translations.value(), lengths_) + .value_or_throw() + ); + } + if (rotation_axis_angles.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(rotation_axis_angles.value(), lengths_) + .value_or_throw() + ); + } + if (quaternions.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(quaternions.value(), lengths_) + .value_or_throw() + ); + } + if (scales.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(scales.value(), lengths_).value_or_throw() + ); + } + if (mat3x3.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(mat3x3.value(), lengths_).value_or_throw() + ); + } + columns.push_back(ComponentColumn::from_indicators( + static_cast(lengths_.size()) + ) + .value_or_throw()); + return columns; + } + + Collection InstancePoses3D::columns() { + if (translations.has_value()) { + return columns(std::vector(translations.value().length(), 1)); + } + if (rotation_axis_angles.has_value()) { + return columns(std::vector(rotation_axis_angles.value().length(), 1)); + } + if (quaternions.has_value()) { + return columns(std::vector(quaternions.value().length(), 1)); + } + if (scales.has_value()) { + return columns(std::vector(scales.value().length(), 1)); + } + if (mat3x3.has_value()) { + return columns(std::vector(mat3x3.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/instance_poses3d.hpp b/rerun_cpp/src/rerun/archetypes/instance_poses3d.hpp index b7c7f1ef1999..f0fb5605bfbd 100644 --- a/rerun_cpp/src/rerun/archetypes/instance_poses3d.hpp +++ b/rerun_cpp/src/rerun/archetypes/instance_poses3d.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/pose_rotation_axis_angle.hpp" #include "../components/pose_rotation_quat.hpp" #include "../components/pose_scale3d.hpp" @@ -184,6 +185,22 @@ namespace rerun::archetypes { mat3x3 = ComponentBatch::from_loggable(_mat3x3, Descriptor_mat3x3).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/line_strips2d.cpp b/rerun_cpp/src/rerun/archetypes/line_strips2d.cpp index ed4d0bfece82..28683ce8edbd 100644 --- a/rerun_cpp/src/rerun/archetypes/line_strips2d.cpp +++ b/rerun_cpp/src/rerun/archetypes/line_strips2d.cpp @@ -27,6 +27,75 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection LineStrips2D::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(8); + if (strips.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(strips.value(), lengths_).value_or_throw() + ); + } + if (radii.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(radii.value(), lengths_).value_or_throw() + ); + } + if (colors.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(colors.value(), lengths_).value_or_throw() + ); + } + if (labels.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(labels.value(), lengths_).value_or_throw() + ); + } + if (show_labels.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(show_labels.value(), lengths_) + .value_or_throw() + ); + } + if (draw_order.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(draw_order.value(), lengths_) + .value_or_throw()); + } + if (class_ids.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(class_ids.value(), lengths_) + .value_or_throw()); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection LineStrips2D::columns() { + if (strips.has_value()) { + return columns(std::vector(strips.value().length(), 1)); + } + if (radii.has_value()) { + return columns(std::vector(radii.value().length(), 1)); + } + if (colors.has_value()) { + return columns(std::vector(colors.value().length(), 1)); + } + if (labels.has_value()) { + return columns(std::vector(labels.value().length(), 1)); + } + if (show_labels.has_value()) { + return columns(std::vector(show_labels.value().length(), 1)); + } + if (draw_order.has_value()) { + return columns(std::vector(draw_order.value().length(), 1)); + } + if (class_ids.has_value()) { + return columns(std::vector(class_ids.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/line_strips2d.hpp b/rerun_cpp/src/rerun/archetypes/line_strips2d.hpp index 4b0deedfdf96..4a0a7691dda9 100644 --- a/rerun_cpp/src/rerun/archetypes/line_strips2d.hpp +++ b/rerun_cpp/src/rerun/archetypes/line_strips2d.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/class_id.hpp" #include "../components/color.hpp" #include "../components/draw_order.hpp" @@ -226,6 +227,22 @@ namespace rerun::archetypes { ComponentBatch::from_loggable(_class_ids, Descriptor_class_ids).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/line_strips3d.cpp b/rerun_cpp/src/rerun/archetypes/line_strips3d.cpp index 946e2c34c61b..c029f7b8d83c 100644 --- a/rerun_cpp/src/rerun/archetypes/line_strips3d.cpp +++ b/rerun_cpp/src/rerun/archetypes/line_strips3d.cpp @@ -24,6 +24,68 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection LineStrips3D::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(7); + if (strips.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(strips.value(), lengths_).value_or_throw() + ); + } + if (radii.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(radii.value(), lengths_).value_or_throw() + ); + } + if (colors.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(colors.value(), lengths_).value_or_throw() + ); + } + if (labels.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(labels.value(), lengths_).value_or_throw() + ); + } + if (show_labels.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(show_labels.value(), lengths_) + .value_or_throw() + ); + } + if (class_ids.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(class_ids.value(), lengths_) + .value_or_throw()); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection LineStrips3D::columns() { + if (strips.has_value()) { + return columns(std::vector(strips.value().length(), 1)); + } + if (radii.has_value()) { + return columns(std::vector(radii.value().length(), 1)); + } + if (colors.has_value()) { + return columns(std::vector(colors.value().length(), 1)); + } + if (labels.has_value()) { + return columns(std::vector(labels.value().length(), 1)); + } + if (show_labels.has_value()) { + return columns(std::vector(show_labels.value().length(), 1)); + } + if (class_ids.has_value()) { + return columns(std::vector(class_ids.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/line_strips3d.hpp b/rerun_cpp/src/rerun/archetypes/line_strips3d.hpp index 7dfc0eb7b659..dfd3c9f5f29c 100644 --- a/rerun_cpp/src/rerun/archetypes/line_strips3d.hpp +++ b/rerun_cpp/src/rerun/archetypes/line_strips3d.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/class_id.hpp" #include "../components/color.hpp" #include "../components/line_strip3d.hpp" @@ -221,6 +222,22 @@ namespace rerun::archetypes { ComponentBatch::from_loggable(_class_ids, Descriptor_class_ids).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/mesh3d.cpp b/rerun_cpp/src/rerun/archetypes/mesh3d.cpp index 9a5ddc3a6890..ef535ed5e41f 100644 --- a/rerun_cpp/src/rerun/archetypes/mesh3d.cpp +++ b/rerun_cpp/src/rerun/archetypes/mesh3d.cpp @@ -37,6 +37,99 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection Mesh3D::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(10); + if (vertex_positions.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(vertex_positions.value(), lengths_) + .value_or_throw() + ); + } + if (triangle_indices.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(triangle_indices.value(), lengths_) + .value_or_throw() + ); + } + if (vertex_normals.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(vertex_normals.value(), lengths_) + .value_or_throw() + ); + } + if (vertex_colors.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(vertex_colors.value(), lengths_) + .value_or_throw() + ); + } + if (vertex_texcoords.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(vertex_texcoords.value(), lengths_) + .value_or_throw() + ); + } + if (albedo_factor.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(albedo_factor.value(), lengths_) + .value_or_throw() + ); + } + if (albedo_texture_buffer.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(albedo_texture_buffer.value(), lengths_) + .value_or_throw() + ); + } + if (albedo_texture_format.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(albedo_texture_format.value(), lengths_) + .value_or_throw() + ); + } + if (class_ids.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(class_ids.value(), lengths_) + .value_or_throw()); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection Mesh3D::columns() { + if (vertex_positions.has_value()) { + return columns(std::vector(vertex_positions.value().length(), 1)); + } + if (triangle_indices.has_value()) { + return columns(std::vector(triangle_indices.value().length(), 1)); + } + if (vertex_normals.has_value()) { + return columns(std::vector(vertex_normals.value().length(), 1)); + } + if (vertex_colors.has_value()) { + return columns(std::vector(vertex_colors.value().length(), 1)); + } + if (vertex_texcoords.has_value()) { + return columns(std::vector(vertex_texcoords.value().length(), 1)); + } + if (albedo_factor.has_value()) { + return columns(std::vector(albedo_factor.value().length(), 1)); + } + if (albedo_texture_buffer.has_value()) { + return columns(std::vector(albedo_texture_buffer.value().length(), 1)); + } + if (albedo_texture_format.has_value()) { + return columns(std::vector(albedo_texture_format.value().length(), 1)); + } + if (class_ids.has_value()) { + return columns(std::vector(class_ids.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/mesh3d.hpp b/rerun_cpp/src/rerun/archetypes/mesh3d.hpp index 45f7f9d8a4e2..5ee8cf58714a 100644 --- a/rerun_cpp/src/rerun/archetypes/mesh3d.hpp +++ b/rerun_cpp/src/rerun/archetypes/mesh3d.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/albedo_factor.hpp" #include "../components/class_id.hpp" #include "../components/color.hpp" @@ -310,6 +311,22 @@ namespace rerun::archetypes { ComponentBatch::from_loggable(_class_ids, Descriptor_class_ids).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/pinhole.cpp b/rerun_cpp/src/rerun/archetypes/pinhole.cpp index bf574f9307df..926abbeb7992 100644 --- a/rerun_cpp/src/rerun/archetypes/pinhole.cpp +++ b/rerun_cpp/src/rerun/archetypes/pinhole.cpp @@ -25,6 +25,52 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection Pinhole::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(5); + if (image_from_camera.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(image_from_camera.value(), lengths_) + .value_or_throw() + ); + } + if (resolution.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(resolution.value(), lengths_) + .value_or_throw()); + } + if (camera_xyz.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(camera_xyz.value(), lengths_) + .value_or_throw()); + } + if (image_plane_distance.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(image_plane_distance.value(), lengths_) + .value_or_throw() + ); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection Pinhole::columns() { + if (image_from_camera.has_value()) { + return columns(std::vector(image_from_camera.value().length(), 1)); + } + if (resolution.has_value()) { + return columns(std::vector(resolution.value().length(), 1)); + } + if (camera_xyz.has_value()) { + return columns(std::vector(camera_xyz.value().length(), 1)); + } + if (image_plane_distance.has_value()) { + return columns(std::vector(image_plane_distance.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/pinhole.hpp b/rerun_cpp/src/rerun/archetypes/pinhole.hpp index ded7c0367a83..f7468a6ab4ba 100644 --- a/rerun_cpp/src/rerun/archetypes/pinhole.hpp +++ b/rerun_cpp/src/rerun/archetypes/pinhole.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/image_plane_distance.hpp" #include "../components/pinhole_projection.hpp" #include "../components/resolution.hpp" @@ -296,6 +297,22 @@ namespace rerun::archetypes { .value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/points2d.cpp b/rerun_cpp/src/rerun/archetypes/points2d.cpp index 23ffb2e60b82..ba33eb2f6bd9 100644 --- a/rerun_cpp/src/rerun/archetypes/points2d.cpp +++ b/rerun_cpp/src/rerun/archetypes/points2d.cpp @@ -31,6 +31,83 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection Points2D::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(9); + if (positions.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(positions.value(), lengths_) + .value_or_throw()); + } + if (radii.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(radii.value(), lengths_).value_or_throw() + ); + } + if (colors.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(colors.value(), lengths_).value_or_throw() + ); + } + if (labels.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(labels.value(), lengths_).value_or_throw() + ); + } + if (show_labels.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(show_labels.value(), lengths_) + .value_or_throw() + ); + } + if (draw_order.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(draw_order.value(), lengths_) + .value_or_throw()); + } + if (class_ids.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(class_ids.value(), lengths_) + .value_or_throw()); + } + if (keypoint_ids.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(keypoint_ids.value(), lengths_) + .value_or_throw() + ); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection Points2D::columns() { + if (positions.has_value()) { + return columns(std::vector(positions.value().length(), 1)); + } + if (radii.has_value()) { + return columns(std::vector(radii.value().length(), 1)); + } + if (colors.has_value()) { + return columns(std::vector(colors.value().length(), 1)); + } + if (labels.has_value()) { + return columns(std::vector(labels.value().length(), 1)); + } + if (show_labels.has_value()) { + return columns(std::vector(show_labels.value().length(), 1)); + } + if (draw_order.has_value()) { + return columns(std::vector(draw_order.value().length(), 1)); + } + if (class_ids.has_value()) { + return columns(std::vector(class_ids.value().length(), 1)); + } + if (keypoint_ids.has_value()) { + return columns(std::vector(keypoint_ids.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/points2d.hpp b/rerun_cpp/src/rerun/archetypes/points2d.hpp index f4e327a72509..695c7955c8de 100644 --- a/rerun_cpp/src/rerun/archetypes/points2d.hpp +++ b/rerun_cpp/src/rerun/archetypes/points2d.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/class_id.hpp" #include "../components/color.hpp" #include "../components/draw_order.hpp" @@ -274,6 +275,22 @@ namespace rerun::archetypes { .value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/points3d.cpp b/rerun_cpp/src/rerun/archetypes/points3d.cpp index ff12f08d9ccf..ee364cc892b0 100644 --- a/rerun_cpp/src/rerun/archetypes/points3d.cpp +++ b/rerun_cpp/src/rerun/archetypes/points3d.cpp @@ -28,6 +28,76 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection Points3D::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(8); + if (positions.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(positions.value(), lengths_) + .value_or_throw()); + } + if (radii.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(radii.value(), lengths_).value_or_throw() + ); + } + if (colors.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(colors.value(), lengths_).value_or_throw() + ); + } + if (labels.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(labels.value(), lengths_).value_or_throw() + ); + } + if (show_labels.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(show_labels.value(), lengths_) + .value_or_throw() + ); + } + if (class_ids.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(class_ids.value(), lengths_) + .value_or_throw()); + } + if (keypoint_ids.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(keypoint_ids.value(), lengths_) + .value_or_throw() + ); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection Points3D::columns() { + if (positions.has_value()) { + return columns(std::vector(positions.value().length(), 1)); + } + if (radii.has_value()) { + return columns(std::vector(radii.value().length(), 1)); + } + if (colors.has_value()) { + return columns(std::vector(colors.value().length(), 1)); + } + if (labels.has_value()) { + return columns(std::vector(labels.value().length(), 1)); + } + if (show_labels.has_value()) { + return columns(std::vector(show_labels.value().length(), 1)); + } + if (class_ids.has_value()) { + return columns(std::vector(class_ids.value().length(), 1)); + } + if (keypoint_ids.has_value()) { + return columns(std::vector(keypoint_ids.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/points3d.hpp b/rerun_cpp/src/rerun/archetypes/points3d.hpp index 7e9f409dd4bb..39e2805a2c6a 100644 --- a/rerun_cpp/src/rerun/archetypes/points3d.hpp +++ b/rerun_cpp/src/rerun/archetypes/points3d.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/class_id.hpp" #include "../components/color.hpp" #include "../components/keypoint_id.hpp" @@ -132,30 +133,13 @@ namespace rerun::archetypes { /// auto times = rerun::Collection{10s, 11s, 12s, 13s, 14s}; /// auto time_column = rerun::TimeColumn::from_times("time", std::move(times)); /// - /// // Interpret raw positions and color data as rerun components and partition them. - /// auto indicator_batch = rerun::ComponentColumn::from_indicators(5); - /// auto position_batch = rerun::ComponentColumn::from_loggable_with_lengths( - /// rerun::Collection(std::move(positions)), - /// {2, 4, 4, 3, 4} - /// ); - /// auto color_batch = rerun::ComponentColumn::from_loggable( - /// rerun::Collection(std::move(colors)) - /// ); - /// auto radius_batch = rerun::ComponentColumn::from_loggable( - /// rerun::Collection(std::move(radii)) - /// ); + /// // Partition our data as expected across the 5 timesteps. + /// auto position = + /// rerun::Points3D::update_fields().with_positions(positions).columns({2, 4, 4, 3, 4}); + /// auto color_and_radius = + /// rerun::Points3D::update_fields().with_colors(colors).with_radii(radii).columns(); /// - /// // TODO(#8754) : use tagged columnar APIs - /// rec.send_columns( - /// "points", - /// time_column, - /// { - /// indicator_batch.value_or_throw(), - /// position_batch.value_or_throw(), - /// color_batch.value_or_throw(), - /// radius_batch.value_or_throw(), - /// } - /// ); + /// rec.send_columns2("points", time_column, position, color_and_radius); /// } /// ``` struct Points3D { @@ -310,6 +294,22 @@ namespace rerun::archetypes { .value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/scalar.cpp b/rerun_cpp/src/rerun/archetypes/scalar.cpp index bad8c3634647..773a19075edc 100644 --- a/rerun_cpp/src/rerun/archetypes/scalar.cpp +++ b/rerun_cpp/src/rerun/archetypes/scalar.cpp @@ -12,6 +12,28 @@ namespace rerun::archetypes { ComponentBatch::empty(Descriptor_scalar).value_or_throw(); return archetype; } + + Collection Scalar::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(2); + if (scalar.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(scalar.value(), lengths_).value_or_throw() + ); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection Scalar::columns() { + if (scalar.has_value()) { + return columns(std::vector(scalar.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/scalar.hpp b/rerun_cpp/src/rerun/archetypes/scalar.hpp index 842b48e85f29..0d042e46ea91 100644 --- a/rerun_cpp/src/rerun/archetypes/scalar.hpp +++ b/rerun_cpp/src/rerun/archetypes/scalar.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/scalar.hpp" #include "../indicator_component.hpp" #include "../result.hpp" @@ -118,6 +119,22 @@ namespace rerun::archetypes { scalar = ComponentBatch::from_loggable(_scalar, Descriptor_scalar).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/segmentation_image.cpp b/rerun_cpp/src/rerun/archetypes/segmentation_image.cpp index 1aa4aaacfb53..43d2c9fdf729 100644 --- a/rerun_cpp/src/rerun/archetypes/segmentation_image.cpp +++ b/rerun_cpp/src/rerun/archetypes/segmentation_image.cpp @@ -19,6 +19,51 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection SegmentationImage::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(5); + if (buffer.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(buffer.value(), lengths_).value_or_throw() + ); + } + if (format.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(format.value(), lengths_).value_or_throw() + ); + } + if (opacity.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(opacity.value(), lengths_).value_or_throw() + ); + } + if (draw_order.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(draw_order.value(), lengths_) + .value_or_throw()); + } + columns.push_back(ComponentColumn::from_indicators( + static_cast(lengths_.size()) + ) + .value_or_throw()); + return columns; + } + + Collection SegmentationImage::columns() { + if (buffer.has_value()) { + return columns(std::vector(buffer.value().length(), 1)); + } + if (format.has_value()) { + return columns(std::vector(format.value().length(), 1)); + } + if (opacity.has_value()) { + return columns(std::vector(opacity.value().length(), 1)); + } + if (draw_order.has_value()) { + return columns(std::vector(draw_order.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/segmentation_image.hpp b/rerun_cpp/src/rerun/archetypes/segmentation_image.hpp index 1f7a418c8227..0f7bd33ad684 100644 --- a/rerun_cpp/src/rerun/archetypes/segmentation_image.hpp +++ b/rerun_cpp/src/rerun/archetypes/segmentation_image.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/draw_order.hpp" #include "../components/image_buffer.hpp" #include "../components/image_format.hpp" @@ -224,6 +225,22 @@ namespace rerun::archetypes { ComponentBatch::from_loggable(_draw_order, Descriptor_draw_order).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/series_line.cpp b/rerun_cpp/src/rerun/archetypes/series_line.cpp index bcab60a9ec1d..c654d2df42a3 100644 --- a/rerun_cpp/src/rerun/archetypes/series_line.cpp +++ b/rerun_cpp/src/rerun/archetypes/series_line.cpp @@ -20,6 +20,53 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection SeriesLine::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(5); + if (color.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(color.value(), lengths_).value_or_throw() + ); + } + if (width.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(width.value(), lengths_).value_or_throw() + ); + } + if (name.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(name.value(), lengths_).value_or_throw() + ); + } + if (aggregation_policy.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(aggregation_policy.value(), lengths_) + .value_or_throw() + ); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection SeriesLine::columns() { + if (color.has_value()) { + return columns(std::vector(color.value().length(), 1)); + } + if (width.has_value()) { + return columns(std::vector(width.value().length(), 1)); + } + if (name.has_value()) { + return columns(std::vector(name.value().length(), 1)); + } + if (aggregation_policy.has_value()) { + return columns(std::vector(aggregation_policy.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/series_line.hpp b/rerun_cpp/src/rerun/archetypes/series_line.hpp index a77969cf69e7..1f54fc0929ae 100644 --- a/rerun_cpp/src/rerun/archetypes/series_line.hpp +++ b/rerun_cpp/src/rerun/archetypes/series_line.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/aggregation_policy.hpp" #include "../components/color.hpp" #include "../components/name.hpp" @@ -156,6 +157,22 @@ namespace rerun::archetypes { .value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/series_point.cpp b/rerun_cpp/src/rerun/archetypes/series_point.cpp index ada0501dfb00..b9f9283863b8 100644 --- a/rerun_cpp/src/rerun/archetypes/series_point.cpp +++ b/rerun_cpp/src/rerun/archetypes/series_point.cpp @@ -19,6 +19,53 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection SeriesPoint::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(5); + if (color.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(color.value(), lengths_).value_or_throw() + ); + } + if (marker.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(marker.value(), lengths_).value_or_throw() + ); + } + if (name.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(name.value(), lengths_).value_or_throw() + ); + } + if (marker_size.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(marker_size.value(), lengths_) + .value_or_throw() + ); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection SeriesPoint::columns() { + if (color.has_value()) { + return columns(std::vector(color.value().length(), 1)); + } + if (marker.has_value()) { + return columns(std::vector(marker.value().length(), 1)); + } + if (name.has_value()) { + return columns(std::vector(name.value().length(), 1)); + } + if (marker_size.has_value()) { + return columns(std::vector(marker_size.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/series_point.hpp b/rerun_cpp/src/rerun/archetypes/series_point.hpp index 68d37453cf00..4d7abb13a964 100644 --- a/rerun_cpp/src/rerun/archetypes/series_point.hpp +++ b/rerun_cpp/src/rerun/archetypes/series_point.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/color.hpp" #include "../components/marker_shape.hpp" #include "../components/marker_size.hpp" @@ -153,6 +154,22 @@ namespace rerun::archetypes { .value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/tensor.cpp b/rerun_cpp/src/rerun/archetypes/tensor.cpp index 6058bb270469..205f9a3b5c95 100644 --- a/rerun_cpp/src/rerun/archetypes/tensor.cpp +++ b/rerun_cpp/src/rerun/archetypes/tensor.cpp @@ -15,6 +15,37 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection Tensor::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(3); + if (data.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(data.value(), lengths_).value_or_throw() + ); + } + if (value_range.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(value_range.value(), lengths_) + .value_or_throw() + ); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection Tensor::columns() { + if (data.has_value()) { + return columns(std::vector(data.value().length(), 1)); + } + if (value_range.has_value()) { + return columns(std::vector(value_range.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/tensor.hpp b/rerun_cpp/src/rerun/archetypes/tensor.hpp index 0930e51cf0da..97c1b2f0c452 100644 --- a/rerun_cpp/src/rerun/archetypes/tensor.hpp +++ b/rerun_cpp/src/rerun/archetypes/tensor.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/tensor_data.hpp" #include "../components/value_range.hpp" #include "../indicator_component.hpp" @@ -158,6 +159,22 @@ namespace rerun::archetypes { .value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/text_document.cpp b/rerun_cpp/src/rerun/archetypes/text_document.cpp index 3d81a7a43295..325eb45a592a 100644 --- a/rerun_cpp/src/rerun/archetypes/text_document.cpp +++ b/rerun_cpp/src/rerun/archetypes/text_document.cpp @@ -15,6 +15,35 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection TextDocument::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(3); + if (text.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(text.value(), lengths_).value_or_throw() + ); + } + if (media_type.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(media_type.value(), lengths_) + .value_or_throw()); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection TextDocument::columns() { + if (text.has_value()) { + return columns(std::vector(text.value().length(), 1)); + } + if (media_type.has_value()) { + return columns(std::vector(media_type.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/text_document.hpp b/rerun_cpp/src/rerun/archetypes/text_document.hpp index a3e51cde808e..4db23a9dd6df 100644 --- a/rerun_cpp/src/rerun/archetypes/text_document.hpp +++ b/rerun_cpp/src/rerun/archetypes/text_document.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/media_type.hpp" #include "../components/text.hpp" #include "../indicator_component.hpp" @@ -142,6 +143,22 @@ namespace rerun::archetypes { ComponentBatch::from_loggable(_media_type, Descriptor_media_type).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/text_log.cpp b/rerun_cpp/src/rerun/archetypes/text_log.cpp index ef4f52c7fc58..13e857555c55 100644 --- a/rerun_cpp/src/rerun/archetypes/text_log.cpp +++ b/rerun_cpp/src/rerun/archetypes/text_log.cpp @@ -16,6 +16,44 @@ namespace rerun::archetypes { ComponentBatch::empty(Descriptor_color).value_or_throw(); return archetype; } + + Collection TextLog::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(4); + if (text.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(text.value(), lengths_).value_or_throw() + ); + } + if (level.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(level.value(), lengths_).value_or_throw() + ); + } + if (color.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(color.value(), lengths_).value_or_throw() + ); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection TextLog::columns() { + if (text.has_value()) { + return columns(std::vector(text.value().length(), 1)); + } + if (level.has_value()) { + return columns(std::vector(level.value().length(), 1)); + } + if (color.has_value()) { + return columns(std::vector(color.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/text_log.hpp b/rerun_cpp/src/rerun/archetypes/text_log.hpp index f14cb443e808..11d432261aeb 100644 --- a/rerun_cpp/src/rerun/archetypes/text_log.hpp +++ b/rerun_cpp/src/rerun/archetypes/text_log.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/color.hpp" #include "../components/text.hpp" #include "../components/text_log_level.hpp" @@ -149,6 +150,22 @@ namespace rerun::archetypes { color = ComponentBatch::from_loggable(_color, Descriptor_color).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/transform3d.cpp b/rerun_cpp/src/rerun/archetypes/transform3d.cpp index 41a372279121..67341326e442 100644 --- a/rerun_cpp/src/rerun/archetypes/transform3d.cpp +++ b/rerun_cpp/src/rerun/archetypes/transform3d.cpp @@ -31,6 +31,77 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection Transform3D::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(8); + if (translation.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(translation.value(), lengths_) + .value_or_throw() + ); + } + if (rotation_axis_angle.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(rotation_axis_angle.value(), lengths_) + .value_or_throw() + ); + } + if (quaternion.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(quaternion.value(), lengths_) + .value_or_throw()); + } + if (scale.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(scale.value(), lengths_).value_or_throw() + ); + } + if (mat3x3.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(mat3x3.value(), lengths_).value_or_throw() + ); + } + if (relation.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(relation.value(), lengths_) + .value_or_throw()); + } + if (axis_length.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(axis_length.value(), lengths_) + .value_or_throw() + ); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection Transform3D::columns() { + if (translation.has_value()) { + return columns(std::vector(translation.value().length(), 1)); + } + if (rotation_axis_angle.has_value()) { + return columns(std::vector(rotation_axis_angle.value().length(), 1)); + } + if (quaternion.has_value()) { + return columns(std::vector(quaternion.value().length(), 1)); + } + if (scale.has_value()) { + return columns(std::vector(scale.value().length(), 1)); + } + if (mat3x3.has_value()) { + return columns(std::vector(mat3x3.value().length(), 1)); + } + if (relation.has_value()) { + return columns(std::vector(relation.value().length(), 1)); + } + if (axis_length.has_value()) { + return columns(std::vector(axis_length.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/transform3d.hpp b/rerun_cpp/src/rerun/archetypes/transform3d.hpp index a84dc338b0bf..11a35cd92f5b 100644 --- a/rerun_cpp/src/rerun/archetypes/transform3d.hpp +++ b/rerun_cpp/src/rerun/archetypes/transform3d.hpp @@ -6,6 +6,7 @@ #include "../collection.hpp" #include "../compiler_utils.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/axis_length.hpp" #include "../components/rotation_axis_angle.hpp" #include "../components/rotation_quat.hpp" @@ -659,6 +660,22 @@ namespace rerun::archetypes { .value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/video_frame_reference.cpp b/rerun_cpp/src/rerun/archetypes/video_frame_reference.cpp index d9ad6f47d77e..23d0b90b174a 100644 --- a/rerun_cpp/src/rerun/archetypes/video_frame_reference.cpp +++ b/rerun_cpp/src/rerun/archetypes/video_frame_reference.cpp @@ -16,6 +16,36 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection VideoFrameReference::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(3); + if (timestamp.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(timestamp.value(), lengths_) + .value_or_throw()); + } + if (video_reference.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(video_reference.value(), lengths_) + .value_or_throw() + ); + } + columns.push_back(ComponentColumn::from_indicators( + static_cast(lengths_.size()) + ) + .value_or_throw()); + return columns; + } + + Collection VideoFrameReference::columns() { + if (timestamp.has_value()) { + return columns(std::vector(timestamp.value().length(), 1)); + } + if (video_reference.has_value()) { + return columns(std::vector(video_reference.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/video_frame_reference.hpp b/rerun_cpp/src/rerun/archetypes/video_frame_reference.hpp index 42be5978f8fa..299a9d6b5a65 100644 --- a/rerun_cpp/src/rerun/archetypes/video_frame_reference.hpp +++ b/rerun_cpp/src/rerun/archetypes/video_frame_reference.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/entity_path.hpp" #include "../components/video_timestamp.hpp" #include "../indicator_component.hpp" @@ -202,6 +203,22 @@ namespace rerun::archetypes { .value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/archetypes/view_coordinates.cpp b/rerun_cpp/src/rerun/archetypes/view_coordinates.cpp index 8a2bf44cce09..2e50be5812a2 100644 --- a/rerun_cpp/src/rerun/archetypes/view_coordinates.cpp +++ b/rerun_cpp/src/rerun/archetypes/view_coordinates.cpp @@ -12,6 +12,28 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection ViewCoordinates::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(2); + if (xyz.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(xyz.value(), lengths_).value_or_throw() + ); + } + columns.push_back(ComponentColumn::from_indicators( + static_cast(lengths_.size()) + ) + .value_or_throw()); + return columns; + } + + Collection ViewCoordinates::columns() { + if (xyz.has_value()) { + return columns(std::vector(xyz.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/archetypes/view_coordinates.hpp b/rerun_cpp/src/rerun/archetypes/view_coordinates.hpp index 9039d34d46ed..224f237a989a 100644 --- a/rerun_cpp/src/rerun/archetypes/view_coordinates.hpp +++ b/rerun_cpp/src/rerun/archetypes/view_coordinates.hpp @@ -5,6 +5,7 @@ #include "../collection.hpp" #include "../component_batch.hpp" +#include "../component_column.hpp" #include "../components/view_coordinates.hpp" #include "../indicator_component.hpp" #include "../rerun_sdk_export.hpp" @@ -343,6 +344,22 @@ namespace rerun::archetypes { xyz = ComponentBatch::from_loggable(_xyz, Descriptor_xyz).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/background.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/background.cpp index 590560159845..36f96072f8de 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/background.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/background.cpp @@ -15,6 +15,36 @@ namespace rerun::blueprint::archetypes { ComponentBatch::empty(Descriptor_color).value_or_throw(); return archetype; } + + Collection Background::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(3); + if (kind.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(kind.value(), lengths_).value_or_throw() + ); + } + if (color.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(color.value(), lengths_).value_or_throw() + ); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection Background::columns() { + if (kind.has_value()) { + return columns(std::vector(kind.value().length(), 1)); + } + if (color.has_value()) { + return columns(std::vector(color.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::blueprint::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/background.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/background.hpp index 041e794fe38c..c1714e0bcd0d 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/background.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/background.hpp @@ -6,6 +6,7 @@ #include "../../blueprint/components/background_kind.hpp" #include "../../collection.hpp" #include "../../component_batch.hpp" +#include "../../component_column.hpp" #include "../../components/color.hpp" #include "../../indicator_component.hpp" #include "../../result.hpp" @@ -73,6 +74,22 @@ namespace rerun::blueprint::archetypes { color = ComponentBatch::from_loggable(_color, Descriptor_color).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::blueprint::archetypes diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/container_blueprint.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/container_blueprint.cpp index b607521b996c..9a6e01623e94 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/container_blueprint.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/container_blueprint.cpp @@ -38,6 +38,83 @@ namespace rerun::blueprint::archetypes { .value_or_throw(); return archetype; } + + Collection ContainerBlueprint::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(9); + if (container_kind.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(container_kind.value(), lengths_) + .value_or_throw() + ); + } + if (display_name.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(display_name.value(), lengths_) + .value_or_throw() + ); + } + if (contents.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(contents.value(), lengths_) + .value_or_throw()); + } + if (col_shares.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(col_shares.value(), lengths_) + .value_or_throw()); + } + if (row_shares.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(row_shares.value(), lengths_) + .value_or_throw()); + } + if (active_tab.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(active_tab.value(), lengths_) + .value_or_throw()); + } + if (visible.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(visible.value(), lengths_).value_or_throw() + ); + } + if (grid_columns.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(grid_columns.value(), lengths_) + .value_or_throw() + ); + } + columns.push_back(ComponentColumn::from_indicators( + static_cast(lengths_.size()) + ) + .value_or_throw()); + return columns; + } + + Collection ContainerBlueprint::columns() { + if (container_kind.has_value()) { + return columns(std::vector(container_kind.value().length(), 1)); + } + if (display_name.has_value()) { + return columns(std::vector(display_name.value().length(), 1)); + } + if (contents.has_value()) { + return columns(std::vector(contents.value().length(), 1)); + } + if (col_shares.has_value()) { + return columns(std::vector(col_shares.value().length(), 1)); + } + if (row_shares.has_value()) { + return columns(std::vector(row_shares.value().length(), 1)); + } + if (active_tab.has_value()) { + return columns(std::vector(active_tab.value().length(), 1)); + } + if (visible.has_value()) { + return columns(std::vector(visible.value().length(), 1)); + } + if (grid_columns.has_value()) { + return columns(std::vector(grid_columns.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::blueprint::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/container_blueprint.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/container_blueprint.hpp index 9cd08daedc65..564eb2aa3db7 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/container_blueprint.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/container_blueprint.hpp @@ -12,6 +12,7 @@ #include "../../blueprint/components/visible.hpp" #include "../../collection.hpp" #include "../../component_batch.hpp" +#include "../../component_column.hpp" #include "../../components/name.hpp" #include "../../indicator_component.hpp" #include "../../result.hpp" @@ -219,6 +220,22 @@ namespace rerun::blueprint::archetypes { .value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::blueprint::archetypes diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/dataframe_query.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/dataframe_query.cpp index a2e97aec62b0..56239fc2fb1a 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/dataframe_query.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/dataframe_query.cpp @@ -31,6 +31,62 @@ namespace rerun::blueprint::archetypes { .value_or_throw(); return archetype; } + + Collection DataframeQuery::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(6); + if (timeline.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(timeline.value(), lengths_) + .value_or_throw()); + } + if (filter_by_range.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(filter_by_range.value(), lengths_) + .value_or_throw() + ); + } + if (filter_is_not_null.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(filter_is_not_null.value(), lengths_) + .value_or_throw() + ); + } + if (apply_latest_at.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(apply_latest_at.value(), lengths_) + .value_or_throw() + ); + } + if (select.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(select.value(), lengths_).value_or_throw() + ); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection DataframeQuery::columns() { + if (timeline.has_value()) { + return columns(std::vector(timeline.value().length(), 1)); + } + if (filter_by_range.has_value()) { + return columns(std::vector(filter_by_range.value().length(), 1)); + } + if (filter_is_not_null.has_value()) { + return columns(std::vector(filter_is_not_null.value().length(), 1)); + } + if (apply_latest_at.has_value()) { + return columns(std::vector(apply_latest_at.value().length(), 1)); + } + if (select.has_value()) { + return columns(std::vector(select.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::blueprint::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/dataframe_query.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/dataframe_query.hpp index 8918e7f6ce6b..89b522c804b4 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/dataframe_query.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/dataframe_query.hpp @@ -10,6 +10,7 @@ #include "../../blueprint/components/timeline_name.hpp" #include "../../collection.hpp" #include "../../component_batch.hpp" +#include "../../component_column.hpp" #include "../../indicator_component.hpp" #include "../../result.hpp" @@ -138,6 +139,22 @@ namespace rerun::blueprint::archetypes { select = ComponentBatch::from_loggable(_select, Descriptor_select).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::blueprint::archetypes diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/force_center.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/force_center.cpp index 92f6f668f671..efaa25a2fe77 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/force_center.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/force_center.cpp @@ -16,6 +16,35 @@ namespace rerun::blueprint::archetypes { .value_or_throw(); return archetype; } + + Collection ForceCenter::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(3); + if (enabled.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(enabled.value(), lengths_).value_or_throw() + ); + } + if (strength.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(strength.value(), lengths_) + .value_or_throw()); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection ForceCenter::columns() { + if (enabled.has_value()) { + return columns(std::vector(enabled.value().length(), 1)); + } + if (strength.has_value()) { + return columns(std::vector(strength.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::blueprint::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/force_center.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/force_center.hpp index 42899c9be4c0..1887ab29c140 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/force_center.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/force_center.hpp @@ -7,6 +7,7 @@ #include "../../blueprint/components/force_strength.hpp" #include "../../collection.hpp" #include "../../component_batch.hpp" +#include "../../component_column.hpp" #include "../../indicator_component.hpp" #include "../../result.hpp" @@ -75,6 +76,22 @@ namespace rerun::blueprint::archetypes { ComponentBatch::from_loggable(_strength, Descriptor_strength).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::blueprint::archetypes diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/force_collision_radius.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/force_collision_radius.cpp index 447c1077bb0d..2c6b8cb5fabd 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/force_collision_radius.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/force_collision_radius.cpp @@ -20,6 +20,43 @@ namespace rerun::blueprint::archetypes { .value_or_throw(); return archetype; } + + Collection ForceCollisionRadius::columns(const Collection& lengths_ + ) { + std::vector columns; + columns.reserve(4); + if (enabled.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(enabled.value(), lengths_).value_or_throw() + ); + } + if (strength.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(strength.value(), lengths_) + .value_or_throw()); + } + if (iterations.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(iterations.value(), lengths_) + .value_or_throw()); + } + columns.push_back(ComponentColumn::from_indicators( + static_cast(lengths_.size()) + ) + .value_or_throw()); + return columns; + } + + Collection ForceCollisionRadius::columns() { + if (enabled.has_value()) { + return columns(std::vector(enabled.value().length(), 1)); + } + if (strength.has_value()) { + return columns(std::vector(strength.value().length(), 1)); + } + if (iterations.has_value()) { + return columns(std::vector(iterations.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::blueprint::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/force_collision_radius.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/force_collision_radius.hpp index 9c1c4e20d2ea..645e78d12983 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/force_collision_radius.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/force_collision_radius.hpp @@ -8,6 +8,7 @@ #include "../../blueprint/components/force_strength.hpp" #include "../../collection.hpp" #include "../../component_batch.hpp" +#include "../../component_column.hpp" #include "../../indicator_component.hpp" #include "../../result.hpp" @@ -101,6 +102,22 @@ namespace rerun::blueprint::archetypes { ComponentBatch::from_loggable(_iterations, Descriptor_iterations).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::blueprint::archetypes diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/force_link.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/force_link.cpp index 59d086a65836..5c8d9d753da1 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/force_link.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/force_link.cpp @@ -20,6 +20,42 @@ namespace rerun::blueprint::archetypes { .value_or_throw(); return archetype; } + + Collection ForceLink::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(4); + if (enabled.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(enabled.value(), lengths_).value_or_throw() + ); + } + if (distance.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(distance.value(), lengths_) + .value_or_throw()); + } + if (iterations.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(iterations.value(), lengths_) + .value_or_throw()); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection ForceLink::columns() { + if (enabled.has_value()) { + return columns(std::vector(enabled.value().length(), 1)); + } + if (distance.has_value()) { + return columns(std::vector(distance.value().length(), 1)); + } + if (iterations.has_value()) { + return columns(std::vector(iterations.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::blueprint::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/force_link.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/force_link.hpp index 19c4932d265e..7241e1f58869 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/force_link.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/force_link.hpp @@ -8,6 +8,7 @@ #include "../../blueprint/components/force_iterations.hpp" #include "../../collection.hpp" #include "../../component_batch.hpp" +#include "../../component_column.hpp" #include "../../indicator_component.hpp" #include "../../result.hpp" @@ -96,6 +97,22 @@ namespace rerun::blueprint::archetypes { ComponentBatch::from_loggable(_iterations, Descriptor_iterations).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::blueprint::archetypes diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/force_many_body.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/force_many_body.cpp index 757618c5c1f8..40cdbf629973 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/force_many_body.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/force_many_body.cpp @@ -16,6 +16,35 @@ namespace rerun::blueprint::archetypes { .value_or_throw(); return archetype; } + + Collection ForceManyBody::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(3); + if (enabled.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(enabled.value(), lengths_).value_or_throw() + ); + } + if (strength.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(strength.value(), lengths_) + .value_or_throw()); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection ForceManyBody::columns() { + if (enabled.has_value()) { + return columns(std::vector(enabled.value().length(), 1)); + } + if (strength.has_value()) { + return columns(std::vector(strength.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::blueprint::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/force_many_body.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/force_many_body.hpp index 63701f68bcdc..4bda598d56a8 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/force_many_body.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/force_many_body.hpp @@ -7,6 +7,7 @@ #include "../../blueprint/components/force_strength.hpp" #include "../../collection.hpp" #include "../../component_batch.hpp" +#include "../../component_column.hpp" #include "../../indicator_component.hpp" #include "../../result.hpp" @@ -84,6 +85,22 @@ namespace rerun::blueprint::archetypes { ComponentBatch::from_loggable(_strength, Descriptor_strength).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::blueprint::archetypes diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/force_position.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/force_position.cpp index 45d7a0913db0..61d23a2af26c 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/force_position.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/force_position.cpp @@ -19,6 +19,42 @@ namespace rerun::blueprint::archetypes { .value_or_throw(); return archetype; } + + Collection ForcePosition::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(4); + if (enabled.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(enabled.value(), lengths_).value_or_throw() + ); + } + if (strength.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(strength.value(), lengths_) + .value_or_throw()); + } + if (position.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(position.value(), lengths_) + .value_or_throw()); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection ForcePosition::columns() { + if (enabled.has_value()) { + return columns(std::vector(enabled.value().length(), 1)); + } + if (strength.has_value()) { + return columns(std::vector(strength.value().length(), 1)); + } + if (position.has_value()) { + return columns(std::vector(position.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::blueprint::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/force_position.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/force_position.hpp index 2af3226f584d..cadcfa0968a6 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/force_position.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/force_position.hpp @@ -7,6 +7,7 @@ #include "../../blueprint/components/force_strength.hpp" #include "../../collection.hpp" #include "../../component_batch.hpp" +#include "../../component_column.hpp" #include "../../components/position2d.hpp" #include "../../indicator_component.hpp" #include "../../result.hpp" @@ -92,6 +93,22 @@ namespace rerun::blueprint::archetypes { ComponentBatch::from_loggable(_position, Descriptor_position).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::blueprint::archetypes diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.cpp index 118023b1c976..d63c0ee6f8f8 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.cpp @@ -23,6 +23,61 @@ namespace rerun::blueprint::archetypes { ComponentBatch::empty(Descriptor_color).value_or_throw(); return archetype; } + + Collection LineGrid3D::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(6); + if (visible.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(visible.value(), lengths_).value_or_throw() + ); + } + if (spacing.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(spacing.value(), lengths_).value_or_throw() + ); + } + if (plane.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(plane.value(), lengths_).value_or_throw() + ); + } + if (stroke_width.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(stroke_width.value(), lengths_) + .value_or_throw() + ); + } + if (color.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(color.value(), lengths_).value_or_throw() + ); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection LineGrid3D::columns() { + if (visible.has_value()) { + return columns(std::vector(visible.value().length(), 1)); + } + if (spacing.has_value()) { + return columns(std::vector(spacing.value().length(), 1)); + } + if (plane.has_value()) { + return columns(std::vector(plane.value().length(), 1)); + } + if (stroke_width.has_value()) { + return columns(std::vector(stroke_width.value().length(), 1)); + } + if (color.has_value()) { + return columns(std::vector(color.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::blueprint::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp index d6f866f4bfab..99fcfba17cb2 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/line_grid3d.hpp @@ -7,6 +7,7 @@ #include "../../blueprint/components/visible.hpp" #include "../../collection.hpp" #include "../../component_batch.hpp" +#include "../../component_column.hpp" #include "../../components/color.hpp" #include "../../components/plane3d.hpp" #include "../../components/stroke_width.hpp" @@ -138,6 +139,22 @@ namespace rerun::blueprint::archetypes { color = ComponentBatch::from_loggable(_color, Descriptor_color).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::blueprint::archetypes diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/map_background.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/map_background.cpp index ac30cb43f832..395631961c44 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/map_background.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/map_background.cpp @@ -13,6 +13,27 @@ namespace rerun::blueprint::archetypes { .value_or_throw(); return archetype; } + + Collection MapBackground::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(2); + if (provider.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(provider.value(), lengths_) + .value_or_throw()); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection MapBackground::columns() { + if (provider.has_value()) { + return columns(std::vector(provider.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::blueprint::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/map_background.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/map_background.hpp index 6a1ce93640eb..3faa72e8e7e5 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/map_background.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/map_background.hpp @@ -6,6 +6,7 @@ #include "../../blueprint/components/map_provider.hpp" #include "../../collection.hpp" #include "../../component_batch.hpp" +#include "../../component_column.hpp" #include "../../indicator_component.hpp" #include "../../result.hpp" @@ -64,6 +65,22 @@ namespace rerun::blueprint::archetypes { ComponentBatch::from_loggable(_provider, Descriptor_provider).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::blueprint::archetypes diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/map_zoom.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/map_zoom.cpp index 66c72513058e..22c6e86f1289 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/map_zoom.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/map_zoom.cpp @@ -13,6 +13,28 @@ namespace rerun::blueprint::archetypes { .value_or_throw(); return archetype; } + + Collection MapZoom::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(2); + if (zoom.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(zoom.value(), lengths_).value_or_throw() + ); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection MapZoom::columns() { + if (zoom.has_value()) { + return columns(std::vector(zoom.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::blueprint::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/map_zoom.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/map_zoom.hpp index a39c63e78045..0538840142dd 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/map_zoom.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/map_zoom.hpp @@ -6,6 +6,7 @@ #include "../../blueprint/components/zoom_level.hpp" #include "../../collection.hpp" #include "../../component_batch.hpp" +#include "../../component_column.hpp" #include "../../indicator_component.hpp" #include "../../result.hpp" @@ -63,6 +64,22 @@ namespace rerun::blueprint::archetypes { zoom = ComponentBatch::from_loggable(_zoom, Descriptor_zoom).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::blueprint::archetypes diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/near_clip_plane.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/near_clip_plane.cpp index 8957d6b381c2..9655cf7e8fa6 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/near_clip_plane.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/near_clip_plane.cpp @@ -15,6 +15,29 @@ namespace rerun::blueprint::archetypes { .value_or_throw(); return archetype; } + + Collection NearClipPlane::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(2); + if (near_clip_plane.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(near_clip_plane.value(), lengths_) + .value_or_throw() + ); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection NearClipPlane::columns() { + if (near_clip_plane.has_value()) { + return columns(std::vector(near_clip_plane.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::blueprint::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/near_clip_plane.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/near_clip_plane.hpp index 96c494f2463d..c7d676d9619e 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/near_clip_plane.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/near_clip_plane.hpp @@ -6,6 +6,7 @@ #include "../../blueprint/components/near_clip_plane.hpp" #include "../../collection.hpp" #include "../../component_batch.hpp" +#include "../../component_column.hpp" #include "../../indicator_component.hpp" #include "../../result.hpp" @@ -69,6 +70,22 @@ namespace rerun::blueprint::archetypes { .value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::blueprint::archetypes diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/panel_blueprint.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/panel_blueprint.cpp index fb44e43b22b7..9119e5485a2d 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/panel_blueprint.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/panel_blueprint.cpp @@ -13,6 +13,28 @@ namespace rerun::blueprint::archetypes { .value_or_throw(); return archetype; } + + Collection PanelBlueprint::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(2); + if (state.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(state.value(), lengths_).value_or_throw() + ); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection PanelBlueprint::columns() { + if (state.has_value()) { + return columns(std::vector(state.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::blueprint::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/panel_blueprint.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/panel_blueprint.hpp index 1b5d644830a4..c40e4c4b174c 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/panel_blueprint.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/panel_blueprint.hpp @@ -6,6 +6,7 @@ #include "../../blueprint/components/panel_state.hpp" #include "../../collection.hpp" #include "../../component_batch.hpp" +#include "../../component_column.hpp" #include "../../indicator_component.hpp" #include "../../result.hpp" @@ -55,6 +56,22 @@ namespace rerun::blueprint::archetypes { state = ComponentBatch::from_loggable(_state, Descriptor_state).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::blueprint::archetypes diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/plot_legend.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/plot_legend.cpp index 933e6549842f..e86c994d4a77 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/plot_legend.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/plot_legend.cpp @@ -16,6 +16,36 @@ namespace rerun::blueprint::archetypes { .value_or_throw(); return archetype; } + + Collection PlotLegend::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(3); + if (corner.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(corner.value(), lengths_).value_or_throw() + ); + } + if (visible.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(visible.value(), lengths_).value_or_throw() + ); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection PlotLegend::columns() { + if (corner.has_value()) { + return columns(std::vector(corner.value().length(), 1)); + } + if (visible.has_value()) { + return columns(std::vector(visible.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::blueprint::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/plot_legend.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/plot_legend.hpp index 9fb02a3c4ed4..dd0ccb373846 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/plot_legend.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/plot_legend.hpp @@ -7,6 +7,7 @@ #include "../../blueprint/components/visible.hpp" #include "../../collection.hpp" #include "../../component_batch.hpp" +#include "../../component_column.hpp" #include "../../indicator_component.hpp" #include "../../result.hpp" @@ -78,6 +79,22 @@ namespace rerun::blueprint::archetypes { visible = ComponentBatch::from_loggable(_visible, Descriptor_visible).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::blueprint::archetypes diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/scalar_axis.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/scalar_axis.cpp index f7f54d449aa5..fc089a96d4ff 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/scalar_axis.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/scalar_axis.cpp @@ -17,6 +17,35 @@ namespace rerun::blueprint::archetypes { .value_or_throw(); return archetype; } + + Collection ScalarAxis::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(3); + if (range.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(range.value(), lengths_).value_or_throw() + ); + } + if (zoom_lock.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(zoom_lock.value(), lengths_) + .value_or_throw()); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection ScalarAxis::columns() { + if (range.has_value()) { + return columns(std::vector(range.value().length(), 1)); + } + if (zoom_lock.has_value()) { + return columns(std::vector(zoom_lock.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::blueprint::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/scalar_axis.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/scalar_axis.hpp index 194ed309f5e9..fcd0dd47302f 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/scalar_axis.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/scalar_axis.hpp @@ -6,6 +6,7 @@ #include "../../blueprint/components/lock_range_during_zoom.hpp" #include "../../collection.hpp" #include "../../component_batch.hpp" +#include "../../component_column.hpp" #include "../../components/range1d.hpp" #include "../../indicator_component.hpp" #include "../../result.hpp" @@ -76,6 +77,22 @@ namespace rerun::blueprint::archetypes { ComponentBatch::from_loggable(_zoom_lock, Descriptor_zoom_lock).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::blueprint::archetypes diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/tensor_scalar_mapping.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/tensor_scalar_mapping.cpp index 3ee67b908f17..24d8c553a865 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/tensor_scalar_mapping.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/tensor_scalar_mapping.cpp @@ -18,6 +18,42 @@ namespace rerun::blueprint::archetypes { .value_or_throw(); return archetype; } + + Collection TensorScalarMapping::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(4); + if (mag_filter.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(mag_filter.value(), lengths_) + .value_or_throw()); + } + if (colormap.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(colormap.value(), lengths_) + .value_or_throw()); + } + if (gamma.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(gamma.value(), lengths_).value_or_throw() + ); + } + columns.push_back(ComponentColumn::from_indicators( + static_cast(lengths_.size()) + ) + .value_or_throw()); + return columns; + } + + Collection TensorScalarMapping::columns() { + if (mag_filter.has_value()) { + return columns(std::vector(mag_filter.value().length(), 1)); + } + if (colormap.has_value()) { + return columns(std::vector(colormap.value().length(), 1)); + } + if (gamma.has_value()) { + return columns(std::vector(gamma.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::blueprint::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/tensor_scalar_mapping.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/tensor_scalar_mapping.hpp index 4773a49ccde5..d9709a3cc32a 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/tensor_scalar_mapping.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/tensor_scalar_mapping.hpp @@ -5,6 +5,7 @@ #include "../../collection.hpp" #include "../../component_batch.hpp" +#include "../../component_column.hpp" #include "../../components/colormap.hpp" #include "../../components/gamma_correction.hpp" #include "../../components/magnification_filter.hpp" @@ -106,6 +107,22 @@ namespace rerun::blueprint::archetypes { gamma = ComponentBatch::from_loggable(_gamma, Descriptor_gamma).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::blueprint::archetypes diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/tensor_slice_selection.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/tensor_slice_selection.cpp index 48bffb17840f..b89e169e738f 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/tensor_slice_selection.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/tensor_slice_selection.cpp @@ -25,6 +25,53 @@ namespace rerun::blueprint::archetypes { .value_or_throw(); return archetype; } + + Collection TensorSliceSelection::columns(const Collection& lengths_ + ) { + std::vector columns; + columns.reserve(5); + if (width.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(width.value(), lengths_).value_or_throw() + ); + } + if (height.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(height.value(), lengths_).value_or_throw() + ); + } + if (indices.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(indices.value(), lengths_).value_or_throw() + ); + } + if (slider.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(slider.value(), lengths_).value_or_throw() + ); + } + columns.push_back(ComponentColumn::from_indicators( + static_cast(lengths_.size()) + ) + .value_or_throw()); + return columns; + } + + Collection TensorSliceSelection::columns() { + if (width.has_value()) { + return columns(std::vector(width.value().length(), 1)); + } + if (height.has_value()) { + return columns(std::vector(height.value().length(), 1)); + } + if (indices.has_value()) { + return columns(std::vector(indices.value().length(), 1)); + } + if (slider.has_value()) { + return columns(std::vector(slider.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::blueprint::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/tensor_slice_selection.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/tensor_slice_selection.hpp index 49d5678504d6..4c341c7a5dcd 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/tensor_slice_selection.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/tensor_slice_selection.hpp @@ -6,6 +6,7 @@ #include "../../blueprint/components/tensor_dimension_index_slider.hpp" #include "../../collection.hpp" #include "../../component_batch.hpp" +#include "../../component_column.hpp" #include "../../components/tensor_dimension_index_selection.hpp" #include "../../components/tensor_height_dimension.hpp" #include "../../components/tensor_width_dimension.hpp" @@ -127,6 +128,22 @@ namespace rerun::blueprint::archetypes { slider = ComponentBatch::from_loggable(_slider, Descriptor_slider).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::blueprint::archetypes diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/tensor_view_fit.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/tensor_view_fit.cpp index d9930607253e..6669ddd484c6 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/tensor_view_fit.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/tensor_view_fit.cpp @@ -13,6 +13,28 @@ namespace rerun::blueprint::archetypes { .value_or_throw(); return archetype; } + + Collection TensorViewFit::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(2); + if (scaling.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(scaling.value(), lengths_).value_or_throw() + ); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection TensorViewFit::columns() { + if (scaling.has_value()) { + return columns(std::vector(scaling.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::blueprint::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/tensor_view_fit.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/tensor_view_fit.hpp index 73ffcd63f67e..abdeb5a14a54 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/tensor_view_fit.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/tensor_view_fit.hpp @@ -6,6 +6,7 @@ #include "../../blueprint/components/view_fit.hpp" #include "../../collection.hpp" #include "../../component_batch.hpp" +#include "../../component_column.hpp" #include "../../indicator_component.hpp" #include "../../result.hpp" @@ -55,6 +56,22 @@ namespace rerun::blueprint::archetypes { scaling = ComponentBatch::from_loggable(_scaling, Descriptor_scaling).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::blueprint::archetypes diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/view_blueprint.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/view_blueprint.cpp index 69f88044b52b..2ece106212f1 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/view_blueprint.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/view_blueprint.cpp @@ -23,6 +23,55 @@ namespace rerun::blueprint::archetypes { .value_or_throw(); return archetype; } + + Collection ViewBlueprint::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(5); + if (class_identifier.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(class_identifier.value(), lengths_) + .value_or_throw() + ); + } + if (display_name.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(display_name.value(), lengths_) + .value_or_throw() + ); + } + if (space_origin.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(space_origin.value(), lengths_) + .value_or_throw() + ); + } + if (visible.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(visible.value(), lengths_).value_or_throw() + ); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection ViewBlueprint::columns() { + if (class_identifier.has_value()) { + return columns(std::vector(class_identifier.value().length(), 1)); + } + if (display_name.has_value()) { + return columns(std::vector(display_name.value().length(), 1)); + } + if (space_origin.has_value()) { + return columns(std::vector(space_origin.value().length(), 1)); + } + if (visible.has_value()) { + return columns(std::vector(visible.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::blueprint::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/view_blueprint.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/view_blueprint.hpp index 2db0735288d2..721b6fbef1d7 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/view_blueprint.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/view_blueprint.hpp @@ -8,6 +8,7 @@ #include "../../blueprint/components/visible.hpp" #include "../../collection.hpp" #include "../../component_batch.hpp" +#include "../../component_column.hpp" #include "../../components/name.hpp" #include "../../indicator_component.hpp" #include "../../result.hpp" @@ -130,6 +131,22 @@ namespace rerun::blueprint::archetypes { visible = ComponentBatch::from_loggable(_visible, Descriptor_visible).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::blueprint::archetypes diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/view_contents.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/view_contents.cpp index 1350503bbe04..2140e17f60c1 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/view_contents.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/view_contents.cpp @@ -13,6 +13,28 @@ namespace rerun::blueprint::archetypes { .value_or_throw(); return archetype; } + + Collection ViewContents::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(2); + if (query.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(query.value(), lengths_).value_or_throw() + ); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection ViewContents::columns() { + if (query.has_value()) { + return columns(std::vector(query.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::blueprint::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/view_contents.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/view_contents.hpp index 73a8e11bf97a..5272ee6eb632 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/view_contents.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/view_contents.hpp @@ -6,6 +6,7 @@ #include "../../blueprint/components/query_expression.hpp" #include "../../collection.hpp" #include "../../component_batch.hpp" +#include "../../component_column.hpp" #include "../../indicator_component.hpp" #include "../../result.hpp" @@ -102,6 +103,22 @@ namespace rerun::blueprint::archetypes { query = ComponentBatch::from_loggable(_query, Descriptor_query).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::blueprint::archetypes diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/viewport_blueprint.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/viewport_blueprint.cpp index 547d9b7ddf22..adf36c90d1cd 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/viewport_blueprint.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/viewport_blueprint.cpp @@ -29,6 +29,62 @@ namespace rerun::blueprint::archetypes { .value_or_throw(); return archetype; } + + Collection ViewportBlueprint::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(6); + if (root_container.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(root_container.value(), lengths_) + .value_or_throw() + ); + } + if (maximized.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(maximized.value(), lengths_) + .value_or_throw()); + } + if (auto_layout.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(auto_layout.value(), lengths_) + .value_or_throw() + ); + } + if (auto_views.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(auto_views.value(), lengths_) + .value_or_throw()); + } + if (past_viewer_recommendations.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths( + past_viewer_recommendations.value(), + lengths_ + ) + .value_or_throw()); + } + columns.push_back(ComponentColumn::from_indicators( + static_cast(lengths_.size()) + ) + .value_or_throw()); + return columns; + } + + Collection ViewportBlueprint::columns() { + if (root_container.has_value()) { + return columns(std::vector(root_container.value().length(), 1)); + } + if (maximized.has_value()) { + return columns(std::vector(maximized.value().length(), 1)); + } + if (auto_layout.has_value()) { + return columns(std::vector(auto_layout.value().length(), 1)); + } + if (auto_views.has_value()) { + return columns(std::vector(auto_views.value().length(), 1)); + } + if (past_viewer_recommendations.has_value()) { + return columns(std::vector(past_viewer_recommendations.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::blueprint::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/viewport_blueprint.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/viewport_blueprint.hpp index 8d5b48462fd7..e2ef5993680a 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/viewport_blueprint.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/viewport_blueprint.hpp @@ -10,6 +10,7 @@ #include "../../blueprint/components/viewer_recommendation_hash.hpp" #include "../../collection.hpp" #include "../../component_batch.hpp" +#include "../../component_column.hpp" #include "../../indicator_component.hpp" #include "../../result.hpp" @@ -160,6 +161,22 @@ namespace rerun::blueprint::archetypes { .value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::blueprint::archetypes diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/visible_time_ranges.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/visible_time_ranges.cpp index c6013adc6cb3..3e04ff3f10e9 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/visible_time_ranges.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/visible_time_ranges.cpp @@ -13,6 +13,28 @@ namespace rerun::blueprint::archetypes { .value_or_throw(); return archetype; } + + Collection VisibleTimeRanges::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(2); + if (ranges.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(ranges.value(), lengths_).value_or_throw() + ); + } + columns.push_back(ComponentColumn::from_indicators( + static_cast(lengths_.size()) + ) + .value_or_throw()); + return columns; + } + + Collection VisibleTimeRanges::columns() { + if (ranges.has_value()) { + return columns(std::vector(ranges.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::blueprint::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/visible_time_ranges.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/visible_time_ranges.hpp index 4c1bf4cb200c..593f611bc706 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/visible_time_ranges.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/visible_time_ranges.hpp @@ -6,6 +6,7 @@ #include "../../blueprint/components/visible_time_range.hpp" #include "../../collection.hpp" #include "../../component_batch.hpp" +#include "../../component_column.hpp" #include "../../indicator_component.hpp" #include "../../result.hpp" @@ -76,6 +77,22 @@ namespace rerun::blueprint::archetypes { ranges = ComponentBatch::from_loggable(_ranges, Descriptor_ranges).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::blueprint::archetypes diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/visual_bounds2d.cpp b/rerun_cpp/src/rerun/blueprint/archetypes/visual_bounds2d.cpp index 5a5e5135abe1..cb45b4415929 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/visual_bounds2d.cpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/visual_bounds2d.cpp @@ -13,6 +13,28 @@ namespace rerun::blueprint::archetypes { .value_or_throw(); return archetype; } + + Collection VisualBounds2D::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(2); + if (range.has_value()) { + columns.push_back( + ComponentColumn::from_batch_with_lengths(range.value(), lengths_).value_or_throw() + ); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection VisualBounds2D::columns() { + if (range.has_value()) { + return columns(std::vector(range.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::blueprint::archetypes namespace rerun { diff --git a/rerun_cpp/src/rerun/blueprint/archetypes/visual_bounds2d.hpp b/rerun_cpp/src/rerun/blueprint/archetypes/visual_bounds2d.hpp index a12ffbe83336..72060e8ee9a3 100644 --- a/rerun_cpp/src/rerun/blueprint/archetypes/visual_bounds2d.hpp +++ b/rerun_cpp/src/rerun/blueprint/archetypes/visual_bounds2d.hpp @@ -6,6 +6,7 @@ #include "../../blueprint/components/visual_bounds2d.hpp" #include "../../collection.hpp" #include "../../component_batch.hpp" +#include "../../component_column.hpp" #include "../../indicator_component.hpp" #include "../../result.hpp" @@ -69,6 +70,22 @@ namespace rerun::blueprint::archetypes { range = ComponentBatch::from_loggable(_range, Descriptor_range).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::blueprint::archetypes diff --git a/rerun_cpp/src/rerun/component_batch.cpp b/rerun_cpp/src/rerun/component_batch.cpp index ec65e74cdd07..931946cf039b 100644 --- a/rerun_cpp/src/rerun/component_batch.cpp +++ b/rerun_cpp/src/rerun/component_batch.cpp @@ -1,5 +1,6 @@ #include "component_batch.hpp" +#include #include #include "c/rerun.h" @@ -13,4 +14,8 @@ namespace rerun { out_component_batch.component_type = component_type; return arrow::ExportArray(*array, &out_component_batch.array, nullptr); } + + size_t ComponentBatch::length() const { + return static_cast(array->length()); + } } // namespace rerun diff --git a/rerun_cpp/src/rerun/component_batch.hpp b/rerun_cpp/src/rerun/component_batch.hpp index 3ada800330cc..9047a405a18d 100644 --- a/rerun_cpp/src/rerun/component_batch.hpp +++ b/rerun_cpp/src/rerun/component_batch.hpp @@ -180,6 +180,9 @@ namespace rerun { } } + /// Size in the number of elements the underlying arrow array contains. + size_t length() const; + /// To rerun C API component batch. /// /// The resulting `rr_component_batch` keeps the `arrow::Array` alive until it is released. diff --git a/rerun_cpp/src/rerun/component_column.cpp b/rerun_cpp/src/rerun/component_column.cpp index 9f3bcf7e9523..d18ea0297542 100644 --- a/rerun_cpp/src/rerun/component_column.cpp +++ b/rerun_cpp/src/rerun/component_column.cpp @@ -9,15 +9,8 @@ #include namespace rerun { - std::shared_ptr ComponentColumn::list_array_type_for( - std::shared_ptr inner_type - ) { - return arrow::list(inner_type); - } - Result ComponentColumn::from_batch_with_lengths( - ComponentBatch batch, const Collection& lengths, - std::shared_ptr list_array_type + ComponentBatch batch, const Collection& lengths ) { // Convert lengths into offsets. std::vector offsets(lengths.size() + 1); @@ -31,17 +24,16 @@ namespace rerun { offsets[i + 1] = offsets[i] + lengths[i]; } - return ComponentColumn::from_batch_with_offsets(batch, std::move(offsets), list_array_type); + return ComponentColumn::from_batch_with_offsets(batch, std::move(offsets)); } Result ComponentColumn::from_batch_with_offsets( - ComponentBatch batch, Collection offsets, - std::shared_ptr list_array_type + ComponentBatch batch, Collection offsets ) { auto length = offsets.size() - 1; auto offset_buffer = arrow_buffer_from_vector(std::move(offsets).to_vector()); auto list_array = std::make_shared( - list_array_type, + arrow::list(batch.array->type()), length, offset_buffer, std::move(batch.array) diff --git a/rerun_cpp/src/rerun/component_column.hpp b/rerun_cpp/src/rerun/component_column.hpp index 19695475e0ae..1eea20dbfb70 100644 --- a/rerun_cpp/src/rerun/component_column.hpp +++ b/rerun_cpp/src/rerun/component_column.hpp @@ -33,19 +33,17 @@ namespace rerun { /// \param lengths The number of components in each run. for `rerun::RecordingStream::send_columns`, /// this specifies the number of components at each time point. /// The sum of the lengths must be equal to the number of components in the batch. + /// \param descriptor Descriptor of the component type for this column. template static Result from_loggable_with_lengths( - const Collection& components, const Collection& lengths + const Collection& components, const Collection& lengths, + const ComponentDescriptor& descriptor = Loggable::Descriptor ) { - auto component_batch_result = ComponentBatch::from_loggable(components); + auto component_batch_result = ComponentBatch::from_loggable(components, descriptor); if (component_batch_result.is_err()) { return component_batch_result.error; } - return from_batch_with_lengths( - component_batch_result.value, - lengths, - list_array_type_for() - ); + return from_batch_with_lengths(component_batch_result.value, lengths); } /// Creates a new component column from a collection of component instances where each run has a length of one. @@ -56,19 +54,30 @@ namespace rerun { /// Automatically registers the component type the first time this type is encountered. /// /// \param components Continuous collection of components which is about to be partitioned into runs of length one. + /// \param descriptor Descriptor of the component type for this column. template - static Result from_loggable(const Collection& components) { + static Result from_loggable( + const Collection& components, + const ComponentDescriptor& descriptor = Loggable::Descriptor + ) { return ComponentColumn::from_loggable_with_lengths( components, - Collection::take_ownership(std::vector(components.size(), 1)) + Collection::take_ownership(std::vector(components.size(), 1)), + descriptor ); } /// Creates a new component column with a given number of archetype indicators for a given archetype type. template static Result from_indicators(uint32_t num_indicators) { - return ComponentColumn::from_loggable( - std::vector(num_indicators) + auto component_batch_result = + ComponentBatch::from_loggable(typename Archetype::IndicatorComponent()); + if (component_batch_result.is_err()) { + return component_batch_result.error; + } + return ComponentColumn::from_batch_with_lengths( + component_batch_result.value, + Collection::take_ownership(std::vector(num_indicators, 0)) ); } @@ -78,11 +87,8 @@ namespace rerun { /// \param lengths The number of components in each run. for `rerun::RecordingStream::send_columns`, /// this specifies the number of components at each time point. /// The sum of the lengths must be equal to the number of components in the batch. - /// \param list_array_type The type of the list array to use for the component column. - /// Can be retrieved using `list_array_type_for()`. static Result from_batch_with_lengths( - ComponentBatch batch, const Collection& lengths, - std::shared_ptr list_array_type + ComponentBatch batch, const Collection& lengths ); /// Creates a new component batch partition from a batch and a collection of component offsets. @@ -94,32 +100,8 @@ namespace rerun { /// E.g. a `ParitionedComponentBatch` with a single component would have an offset array of `[0, 1]`. /// A `ComponentColumn` with 5 components divided into runs of length 2 and 3 // would have an offset array of `[0, 2, 5]`. - /// \param list_array_type The type of the list array to use for the component column. - /// Can be retrieved using `list_array_type_for()`. static Result from_batch_with_offsets( - ComponentBatch batch, Collection offsets, - std::shared_ptr list_array_type - ); - - /// Returns the list array type for the given loggable type. - /// - /// Lazily creates the type on first call and then returns a reference to it. - template - static const std::shared_ptr& list_array_type_for() { - static_assert( - rerun::is_loggable, - "The given type does not implement the rerun::Loggable trait." - ); - static std::shared_ptr data_type = - list_array_type_for(Loggable::arrow_datatype()); - return data_type; - } - - /// Creates a new arrow::Datatype for an underlying type. - /// - /// To avoid repeated allocation, use the templated version of this method. - static std::shared_ptr list_array_type_for( - std::shared_ptr inner_type + ComponentBatch batch, Collection offsets ); /// To rerun C API component batch. diff --git a/rerun_cpp/src/rerun/recording_stream.hpp b/rerun_cpp/src/rerun/recording_stream.hpp index 88f68415373d..c073e9b4dbdb 100644 --- a/rerun_cpp/src/rerun/recording_stream.hpp +++ b/rerun_cpp/src/rerun/recording_stream.hpp @@ -717,6 +717,75 @@ namespace rerun { return try_send_columns(entity_path, time_columns, std::move(serialized_columns)); } + /// Directly log a columns of data to Rerun. + /// + /// This variant takes in arbitrary amount of `ComponentColumn`s and `ComponentColumn` collections. + /// + /// Unlike the regular `log` API, which is row-oriented, this API lets you submit the data + /// in a columnar form. Each `TimeColumn` and `ComponentColumn` represents a column of data that will be sent to Rerun. + /// The lengths of all of these columns must match, and all + /// data that shares the same index across the different columns will act as a single logical row, + /// equivalent to a single call to `RecordingStream::log`. + /// + /// Note that this API ignores any stateful time set on the log stream via the `RecordingStream::set_time_*` APIs. + /// Furthermore, this will _not_ inject the default timelines `log_tick` and `log_time` timeline columns. + /// + /// Any failures that may occur during serialization are handled with `Error::handle`. + /// + /// \param entity_path Path to the entity in the space hierarchy. + /// \param time_columns The time columns to send. + /// \param component_columns The columns of components to send. Both individual `ComponentColumn`s and `Collection`s are accepted. + /// \see `try_send_columns` + template + void send_columns2( + std::string_view entity_path, Collection time_columns, + Ts... component_columns // NOLINT + ) const { + try_send_columns2(entity_path, time_columns, component_columns...).handle(); + } + + /// Directly log a columns of data to Rerun. + /// + /// This variant takes in arbitrary amount of `ComponentColumn`s and `ComponentColumn` collections. + /// + /// Unlike the regular `log` API, which is row-oriented, this API lets you submit the data + /// in a columnar form. Each `TimeColumn` and `ComponentColumn` represents a column of data that will be sent to Rerun. + /// The lengths of all of these columns must match, and all + /// data that shares the same index across the different columns will act as a single logical row, + /// equivalent to a single call to `RecordingStream::log`. + /// + /// Note that this API ignores any stateful time set on the log stream via the `RecordingStream::set_time_*` APIs. + /// Furthermore, this will _not_ inject the default timelines `log_tick` and `log_time` timeline columns. + /// + /// \param entity_path Path to the entity in the space hierarchy. + /// \param time_columns The time columns to send. + /// \param component_columns The columns of components to send. Both individual `ComponentColumn`s and `Collection`s are accepted. + /// \see `send_columns` + template + Error try_send_columns2( + std::string_view entity_path, Collection time_columns, + Ts... component_columns // NOLINT + ) const { + std::vector flat_column_list; + ( + [&] { + static_assert( + std::is_same_v, ComponentColumn> || + std::is_constructible_v, Ts>, + "Ts must be ComponentColumn or a collection thereof" + ); + + push_back_columns(flat_column_list, std::move(component_columns)); + }(), + ... + ); + return try_send_columns( + entity_path, + std::move(time_columns), + std::move(flat_column_list) + ); + } + /// Directly log a columns of data to Rerun. /// /// Unlike the regular `log` API, which is row-oriented, this API lets you submit the data @@ -764,6 +833,21 @@ namespace rerun { /// @} private: + // Utility function to implement `try_send_columns` variadic template. + static void push_back_columns( + std::vector& component_columns, Collection new_columns + ) { + for (const auto& new_column : new_columns) { + component_columns.emplace_back(std::move(new_column)); + } + } + + static void push_back_columns( + std::vector& component_columns, ComponentColumn new_column + ) { + component_columns.emplace_back(std::move(new_column)); + } + RecordingStream(uint32_t id, StoreKind store_kind); uint32_t _id; diff --git a/rerun_cpp/tests/generated/archetypes/affix_fuzzer1.cpp b/rerun_cpp/tests/generated/archetypes/affix_fuzzer1.cpp index a246cd4b21b1..e25054b48b63 100644 --- a/rerun_cpp/tests/generated/archetypes/affix_fuzzer1.cpp +++ b/rerun_cpp/tests/generated/archetypes/affix_fuzzer1.cpp @@ -76,6 +76,174 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection AffixFuzzer1::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(23); + if (fuzz1001.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1001.value(), lengths_) + .value_or_throw()); + } + if (fuzz1002.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1002.value(), lengths_) + .value_or_throw()); + } + if (fuzz1003.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1003.value(), lengths_) + .value_or_throw()); + } + if (fuzz1004.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1004.value(), lengths_) + .value_or_throw()); + } + if (fuzz1005.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1005.value(), lengths_) + .value_or_throw()); + } + if (fuzz1006.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1006.value(), lengths_) + .value_or_throw()); + } + if (fuzz1007.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1007.value(), lengths_) + .value_or_throw()); + } + if (fuzz1008.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1008.value(), lengths_) + .value_or_throw()); + } + if (fuzz1009.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1009.value(), lengths_) + .value_or_throw()); + } + if (fuzz1010.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1010.value(), lengths_) + .value_or_throw()); + } + if (fuzz1011.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1011.value(), lengths_) + .value_or_throw()); + } + if (fuzz1012.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1012.value(), lengths_) + .value_or_throw()); + } + if (fuzz1013.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1013.value(), lengths_) + .value_or_throw()); + } + if (fuzz1014.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1014.value(), lengths_) + .value_or_throw()); + } + if (fuzz1015.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1015.value(), lengths_) + .value_or_throw()); + } + if (fuzz1016.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1016.value(), lengths_) + .value_or_throw()); + } + if (fuzz1017.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1017.value(), lengths_) + .value_or_throw()); + } + if (fuzz1018.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1018.value(), lengths_) + .value_or_throw()); + } + if (fuzz1019.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1019.value(), lengths_) + .value_or_throw()); + } + if (fuzz1020.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1020.value(), lengths_) + .value_or_throw()); + } + if (fuzz1021.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1021.value(), lengths_) + .value_or_throw()); + } + if (fuzz1022.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1022.value(), lengths_) + .value_or_throw()); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection AffixFuzzer1::columns() { + if (fuzz1001.has_value()) { + return columns(std::vector(fuzz1001.value().length(), 1)); + } + if (fuzz1002.has_value()) { + return columns(std::vector(fuzz1002.value().length(), 1)); + } + if (fuzz1003.has_value()) { + return columns(std::vector(fuzz1003.value().length(), 1)); + } + if (fuzz1004.has_value()) { + return columns(std::vector(fuzz1004.value().length(), 1)); + } + if (fuzz1005.has_value()) { + return columns(std::vector(fuzz1005.value().length(), 1)); + } + if (fuzz1006.has_value()) { + return columns(std::vector(fuzz1006.value().length(), 1)); + } + if (fuzz1007.has_value()) { + return columns(std::vector(fuzz1007.value().length(), 1)); + } + if (fuzz1008.has_value()) { + return columns(std::vector(fuzz1008.value().length(), 1)); + } + if (fuzz1009.has_value()) { + return columns(std::vector(fuzz1009.value().length(), 1)); + } + if (fuzz1010.has_value()) { + return columns(std::vector(fuzz1010.value().length(), 1)); + } + if (fuzz1011.has_value()) { + return columns(std::vector(fuzz1011.value().length(), 1)); + } + if (fuzz1012.has_value()) { + return columns(std::vector(fuzz1012.value().length(), 1)); + } + if (fuzz1013.has_value()) { + return columns(std::vector(fuzz1013.value().length(), 1)); + } + if (fuzz1014.has_value()) { + return columns(std::vector(fuzz1014.value().length(), 1)); + } + if (fuzz1015.has_value()) { + return columns(std::vector(fuzz1015.value().length(), 1)); + } + if (fuzz1016.has_value()) { + return columns(std::vector(fuzz1016.value().length(), 1)); + } + if (fuzz1017.has_value()) { + return columns(std::vector(fuzz1017.value().length(), 1)); + } + if (fuzz1018.has_value()) { + return columns(std::vector(fuzz1018.value().length(), 1)); + } + if (fuzz1019.has_value()) { + return columns(std::vector(fuzz1019.value().length(), 1)); + } + if (fuzz1020.has_value()) { + return columns(std::vector(fuzz1020.value().length(), 1)); + } + if (fuzz1021.has_value()) { + return columns(std::vector(fuzz1021.value().length(), 1)); + } + if (fuzz1022.has_value()) { + return columns(std::vector(fuzz1022.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/tests/generated/archetypes/affix_fuzzer1.hpp b/rerun_cpp/tests/generated/archetypes/affix_fuzzer1.hpp index cb270b82eeb3..350d801f9c0d 100644 --- a/rerun_cpp/tests/generated/archetypes/affix_fuzzer1.hpp +++ b/rerun_cpp/tests/generated/archetypes/affix_fuzzer1.hpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -405,6 +406,22 @@ namespace rerun::archetypes { ComponentBatch::from_loggable(_fuzz1022, Descriptor_fuzz1022).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/tests/generated/archetypes/affix_fuzzer2.cpp b/rerun_cpp/tests/generated/archetypes/affix_fuzzer2.cpp index 5e1e5deb4aaf..5fd61a0841f0 100644 --- a/rerun_cpp/tests/generated/archetypes/affix_fuzzer2.cpp +++ b/rerun_cpp/tests/generated/archetypes/affix_fuzzer2.cpp @@ -67,6 +67,153 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection AffixFuzzer2::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(20); + if (fuzz1101.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1101.value(), lengths_) + .value_or_throw()); + } + if (fuzz1102.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1102.value(), lengths_) + .value_or_throw()); + } + if (fuzz1103.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1103.value(), lengths_) + .value_or_throw()); + } + if (fuzz1104.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1104.value(), lengths_) + .value_or_throw()); + } + if (fuzz1105.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1105.value(), lengths_) + .value_or_throw()); + } + if (fuzz1106.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1106.value(), lengths_) + .value_or_throw()); + } + if (fuzz1107.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1107.value(), lengths_) + .value_or_throw()); + } + if (fuzz1108.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1108.value(), lengths_) + .value_or_throw()); + } + if (fuzz1109.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1109.value(), lengths_) + .value_or_throw()); + } + if (fuzz1110.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1110.value(), lengths_) + .value_or_throw()); + } + if (fuzz1111.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1111.value(), lengths_) + .value_or_throw()); + } + if (fuzz1112.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1112.value(), lengths_) + .value_or_throw()); + } + if (fuzz1113.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1113.value(), lengths_) + .value_or_throw()); + } + if (fuzz1114.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1114.value(), lengths_) + .value_or_throw()); + } + if (fuzz1115.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1115.value(), lengths_) + .value_or_throw()); + } + if (fuzz1116.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1116.value(), lengths_) + .value_or_throw()); + } + if (fuzz1117.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1117.value(), lengths_) + .value_or_throw()); + } + if (fuzz1118.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1118.value(), lengths_) + .value_or_throw()); + } + if (fuzz1122.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz1122.value(), lengths_) + .value_or_throw()); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection AffixFuzzer2::columns() { + if (fuzz1101.has_value()) { + return columns(std::vector(fuzz1101.value().length(), 1)); + } + if (fuzz1102.has_value()) { + return columns(std::vector(fuzz1102.value().length(), 1)); + } + if (fuzz1103.has_value()) { + return columns(std::vector(fuzz1103.value().length(), 1)); + } + if (fuzz1104.has_value()) { + return columns(std::vector(fuzz1104.value().length(), 1)); + } + if (fuzz1105.has_value()) { + return columns(std::vector(fuzz1105.value().length(), 1)); + } + if (fuzz1106.has_value()) { + return columns(std::vector(fuzz1106.value().length(), 1)); + } + if (fuzz1107.has_value()) { + return columns(std::vector(fuzz1107.value().length(), 1)); + } + if (fuzz1108.has_value()) { + return columns(std::vector(fuzz1108.value().length(), 1)); + } + if (fuzz1109.has_value()) { + return columns(std::vector(fuzz1109.value().length(), 1)); + } + if (fuzz1110.has_value()) { + return columns(std::vector(fuzz1110.value().length(), 1)); + } + if (fuzz1111.has_value()) { + return columns(std::vector(fuzz1111.value().length(), 1)); + } + if (fuzz1112.has_value()) { + return columns(std::vector(fuzz1112.value().length(), 1)); + } + if (fuzz1113.has_value()) { + return columns(std::vector(fuzz1113.value().length(), 1)); + } + if (fuzz1114.has_value()) { + return columns(std::vector(fuzz1114.value().length(), 1)); + } + if (fuzz1115.has_value()) { + return columns(std::vector(fuzz1115.value().length(), 1)); + } + if (fuzz1116.has_value()) { + return columns(std::vector(fuzz1116.value().length(), 1)); + } + if (fuzz1117.has_value()) { + return columns(std::vector(fuzz1117.value().length(), 1)); + } + if (fuzz1118.has_value()) { + return columns(std::vector(fuzz1118.value().length(), 1)); + } + if (fuzz1122.has_value()) { + return columns(std::vector(fuzz1122.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/tests/generated/archetypes/affix_fuzzer2.hpp b/rerun_cpp/tests/generated/archetypes/affix_fuzzer2.hpp index 7683b5f5b5a8..a0e6231d27bf 100644 --- a/rerun_cpp/tests/generated/archetypes/affix_fuzzer2.hpp +++ b/rerun_cpp/tests/generated/archetypes/affix_fuzzer2.hpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -384,6 +385,22 @@ namespace rerun::archetypes { ComponentBatch::from_loggable(_fuzz1122, Descriptor_fuzz1122).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/tests/generated/archetypes/affix_fuzzer3.cpp b/rerun_cpp/tests/generated/archetypes/affix_fuzzer3.cpp index ef8a91d022de..cf1efc446265 100644 --- a/rerun_cpp/tests/generated/archetypes/affix_fuzzer3.cpp +++ b/rerun_cpp/tests/generated/archetypes/affix_fuzzer3.cpp @@ -64,6 +64,146 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection AffixFuzzer3::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(19); + if (fuzz2001.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2001.value(), lengths_) + .value_or_throw()); + } + if (fuzz2002.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2002.value(), lengths_) + .value_or_throw()); + } + if (fuzz2003.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2003.value(), lengths_) + .value_or_throw()); + } + if (fuzz2004.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2004.value(), lengths_) + .value_or_throw()); + } + if (fuzz2005.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2005.value(), lengths_) + .value_or_throw()); + } + if (fuzz2006.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2006.value(), lengths_) + .value_or_throw()); + } + if (fuzz2007.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2007.value(), lengths_) + .value_or_throw()); + } + if (fuzz2008.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2008.value(), lengths_) + .value_or_throw()); + } + if (fuzz2009.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2009.value(), lengths_) + .value_or_throw()); + } + if (fuzz2010.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2010.value(), lengths_) + .value_or_throw()); + } + if (fuzz2011.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2011.value(), lengths_) + .value_or_throw()); + } + if (fuzz2012.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2012.value(), lengths_) + .value_or_throw()); + } + if (fuzz2013.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2013.value(), lengths_) + .value_or_throw()); + } + if (fuzz2014.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2014.value(), lengths_) + .value_or_throw()); + } + if (fuzz2015.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2015.value(), lengths_) + .value_or_throw()); + } + if (fuzz2016.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2016.value(), lengths_) + .value_or_throw()); + } + if (fuzz2017.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2017.value(), lengths_) + .value_or_throw()); + } + if (fuzz2018.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2018.value(), lengths_) + .value_or_throw()); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection AffixFuzzer3::columns() { + if (fuzz2001.has_value()) { + return columns(std::vector(fuzz2001.value().length(), 1)); + } + if (fuzz2002.has_value()) { + return columns(std::vector(fuzz2002.value().length(), 1)); + } + if (fuzz2003.has_value()) { + return columns(std::vector(fuzz2003.value().length(), 1)); + } + if (fuzz2004.has_value()) { + return columns(std::vector(fuzz2004.value().length(), 1)); + } + if (fuzz2005.has_value()) { + return columns(std::vector(fuzz2005.value().length(), 1)); + } + if (fuzz2006.has_value()) { + return columns(std::vector(fuzz2006.value().length(), 1)); + } + if (fuzz2007.has_value()) { + return columns(std::vector(fuzz2007.value().length(), 1)); + } + if (fuzz2008.has_value()) { + return columns(std::vector(fuzz2008.value().length(), 1)); + } + if (fuzz2009.has_value()) { + return columns(std::vector(fuzz2009.value().length(), 1)); + } + if (fuzz2010.has_value()) { + return columns(std::vector(fuzz2010.value().length(), 1)); + } + if (fuzz2011.has_value()) { + return columns(std::vector(fuzz2011.value().length(), 1)); + } + if (fuzz2012.has_value()) { + return columns(std::vector(fuzz2012.value().length(), 1)); + } + if (fuzz2013.has_value()) { + return columns(std::vector(fuzz2013.value().length(), 1)); + } + if (fuzz2014.has_value()) { + return columns(std::vector(fuzz2014.value().length(), 1)); + } + if (fuzz2015.has_value()) { + return columns(std::vector(fuzz2015.value().length(), 1)); + } + if (fuzz2016.has_value()) { + return columns(std::vector(fuzz2016.value().length(), 1)); + } + if (fuzz2017.has_value()) { + return columns(std::vector(fuzz2017.value().length(), 1)); + } + if (fuzz2018.has_value()) { + return columns(std::vector(fuzz2018.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/tests/generated/archetypes/affix_fuzzer3.hpp b/rerun_cpp/tests/generated/archetypes/affix_fuzzer3.hpp index eda8dad54100..6e757f282f4c 100644 --- a/rerun_cpp/tests/generated/archetypes/affix_fuzzer3.hpp +++ b/rerun_cpp/tests/generated/archetypes/affix_fuzzer3.hpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -291,6 +292,22 @@ namespace rerun::archetypes { ComponentBatch::from_loggable(_fuzz2018, Descriptor_fuzz2018).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes diff --git a/rerun_cpp/tests/generated/archetypes/affix_fuzzer4.cpp b/rerun_cpp/tests/generated/archetypes/affix_fuzzer4.cpp index b2b02daaae39..16093b3189cb 100644 --- a/rerun_cpp/tests/generated/archetypes/affix_fuzzer4.cpp +++ b/rerun_cpp/tests/generated/archetypes/affix_fuzzer4.cpp @@ -64,6 +64,146 @@ namespace rerun::archetypes { .value_or_throw(); return archetype; } + + Collection AffixFuzzer4::columns(const Collection& lengths_) { + std::vector columns; + columns.reserve(19); + if (fuzz2101.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2101.value(), lengths_) + .value_or_throw()); + } + if (fuzz2102.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2102.value(), lengths_) + .value_or_throw()); + } + if (fuzz2103.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2103.value(), lengths_) + .value_or_throw()); + } + if (fuzz2104.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2104.value(), lengths_) + .value_or_throw()); + } + if (fuzz2105.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2105.value(), lengths_) + .value_or_throw()); + } + if (fuzz2106.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2106.value(), lengths_) + .value_or_throw()); + } + if (fuzz2107.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2107.value(), lengths_) + .value_or_throw()); + } + if (fuzz2108.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2108.value(), lengths_) + .value_or_throw()); + } + if (fuzz2109.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2109.value(), lengths_) + .value_or_throw()); + } + if (fuzz2110.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2110.value(), lengths_) + .value_or_throw()); + } + if (fuzz2111.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2111.value(), lengths_) + .value_or_throw()); + } + if (fuzz2112.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2112.value(), lengths_) + .value_or_throw()); + } + if (fuzz2113.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2113.value(), lengths_) + .value_or_throw()); + } + if (fuzz2114.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2114.value(), lengths_) + .value_or_throw()); + } + if (fuzz2115.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2115.value(), lengths_) + .value_or_throw()); + } + if (fuzz2116.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2116.value(), lengths_) + .value_or_throw()); + } + if (fuzz2117.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2117.value(), lengths_) + .value_or_throw()); + } + if (fuzz2118.has_value()) { + columns.push_back(ComponentColumn::from_batch_with_lengths(fuzz2118.value(), lengths_) + .value_or_throw()); + } + columns.push_back( + ComponentColumn::from_indicators(static_cast(lengths_.size())) + .value_or_throw() + ); + return columns; + } + + Collection AffixFuzzer4::columns() { + if (fuzz2101.has_value()) { + return columns(std::vector(fuzz2101.value().length(), 1)); + } + if (fuzz2102.has_value()) { + return columns(std::vector(fuzz2102.value().length(), 1)); + } + if (fuzz2103.has_value()) { + return columns(std::vector(fuzz2103.value().length(), 1)); + } + if (fuzz2104.has_value()) { + return columns(std::vector(fuzz2104.value().length(), 1)); + } + if (fuzz2105.has_value()) { + return columns(std::vector(fuzz2105.value().length(), 1)); + } + if (fuzz2106.has_value()) { + return columns(std::vector(fuzz2106.value().length(), 1)); + } + if (fuzz2107.has_value()) { + return columns(std::vector(fuzz2107.value().length(), 1)); + } + if (fuzz2108.has_value()) { + return columns(std::vector(fuzz2108.value().length(), 1)); + } + if (fuzz2109.has_value()) { + return columns(std::vector(fuzz2109.value().length(), 1)); + } + if (fuzz2110.has_value()) { + return columns(std::vector(fuzz2110.value().length(), 1)); + } + if (fuzz2111.has_value()) { + return columns(std::vector(fuzz2111.value().length(), 1)); + } + if (fuzz2112.has_value()) { + return columns(std::vector(fuzz2112.value().length(), 1)); + } + if (fuzz2113.has_value()) { + return columns(std::vector(fuzz2113.value().length(), 1)); + } + if (fuzz2114.has_value()) { + return columns(std::vector(fuzz2114.value().length(), 1)); + } + if (fuzz2115.has_value()) { + return columns(std::vector(fuzz2115.value().length(), 1)); + } + if (fuzz2116.has_value()) { + return columns(std::vector(fuzz2116.value().length(), 1)); + } + if (fuzz2117.has_value()) { + return columns(std::vector(fuzz2117.value().length(), 1)); + } + if (fuzz2118.has_value()) { + return columns(std::vector(fuzz2118.value().length(), 1)); + } + return Collection(); + } } // namespace rerun::archetypes namespace rerun { diff --git a/rerun_cpp/tests/generated/archetypes/affix_fuzzer4.hpp b/rerun_cpp/tests/generated/archetypes/affix_fuzzer4.hpp index 3da99e00180f..7dc1aab65a28 100644 --- a/rerun_cpp/tests/generated/archetypes/affix_fuzzer4.hpp +++ b/rerun_cpp/tests/generated/archetypes/affix_fuzzer4.hpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -309,6 +310,22 @@ namespace rerun::archetypes { ComponentBatch::from_loggable(_fuzz2118, Descriptor_fuzz2118).value_or_throw(); return std::move(*this); } + + /// Partitions the component data into multiple sub-batches. + /// + /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s + /// instead, via `ComponentColumn::from_batch_with_lengths`. + /// + /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun. + /// + /// The specified `lengths` must sum to the total length of the component batch. + Collection columns(const Collection& lengths_); + + /// Partitions the component data into unit-length sub-batches. + /// + /// This is semantically similar to calling `columns` with `std::vector(n, 1)`, + /// where `n` is automatically guessed. + Collection columns(); }; } // namespace rerun::archetypes