MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ write_network_geometry_buffer_sample()

bool MayaFlux::IO::write_network_geometry_buffer_sample ( SpatialCache cache,
const std::string &  stream_name,
const std::shared_ptr< Buffers::NetworkGeometryBuffer > &  buffer 
)

Pack a NetworkGeometryBuffer's driving network into one or more SpatialCache streams, choosing CPU or GPU readback depending on whether the network's CPU-side vertex state is still authoritative.

A GpuFieldOperator anywhere in the network's operator chain (detected via OperatorChain::find<GpuFieldOperator>()) means vertex positions are mutated directly on the GPU: the CPU-side GraphicsOperator buffer write_operator_sample() would otherwise read is stale. In that case this downloads the live vertex bytes straight from the buffer itself (it is a VKBuffer, so the same download_from_gpu_async() pattern download_compute_mesh() uses for ComputeMeshBuffer applies directly), using the still-CPU-tracked get_vertex_count()/get_vertex_layout()/ declared_topology() for population size, record schema, and sample shape (these describe the buffer's contract, not its live GPU bytes, so they stay valid regardless of which side owns the vertex data), then reads the downloaded bytes as Kakshya::Vertex records exactly as write_operator_sample() reads them from CPU memory: color, scalar, uv, normal, and tangent all come along with position, since the record schema is unchanged by which side owns the bytes; only the transfer differs. A curve topology chunks on build_cluster_ids() the same way write_operator_sample() does, since graph/path membership is structural and unaffected by what a GpuFieldOperator does to positions. Also attaches the declared hash_cluster_id state field as a "cluster" attribute when present. Written as a single stream named stream_name: once GPU-driven, the buffer is one flat array and no longer separable by originating operator. Velocities and any per-rule state beyond hash_cluster_id are left out deliberately, the same way relaxation_grid_positions() leaves per-cell state to the caller: a GpuFieldOperator's own bespoke state fields have no shape this function can decode generically.

Without a GpuFieldOperator, every GraphicsOperator on the network (its primary operator plus any in get_operator_chain()) is CPU-readable and each is written through write_operator_sample() as its own set: a network with exactly one GraphicsOperator keeps the plain stream_name unchanged, while a network chaining several writes one child stream per operator, named "<stream_name>_<get_type_name()>" (a trailing index appended for a repeated type), the same role multiple named aiMesh entries play for a multi-submesh ModelWriter export. A per-operator "cluster" attribute (from that operator's own build_cluster_ids()) continues to mark distinct populations within one operator, e.g. PhysicsOperator's collections.

Parameters
cacheTarget cache, already open().
stream_nameStream (or stream-name prefix, if the network chains several GraphicsOperators) to write.
bufferSource buffer. Must be non-null, with a non-null network exposing at least one GraphicsOperator.
Returns
False if buffer/network is missing, no GraphicsOperator is found, or any underlying write_operator_sample()/cache.write() call fails.

Definition at line 356 of file SpatialExport.cpp.

360{
361 if (!buffer) {
362 MF_ERROR(Journal::Component::IO, Journal::Context::FileIO,
363 "write_network_geometry_buffer_sample: null buffer");
364 return false;
365 }
366
367 auto network = buffer->get_network();
368 if (!network) {
369 MF_ERROR(Journal::Component::IO, Journal::Context::FileIO,
370 "write_network_geometry_buffer_sample: buffer has no network");
371 return false;
372 }
373
374 auto chain = network->get_operator_chain();
375
376 if (chain && chain->find<Nodes::Network::GpuFieldOperator>()) {
377 auto* graphics_op = dynamic_cast<Nodes::Network::GraphicsOperator*>(network->get_operator());
378 if (!graphics_op) {
379 MF_ERROR(Journal::Component::IO, Journal::Context::FileIO,
380 "write_network_geometry_buffer_sample: network's primary operator is not a GraphicsOperator");
381 return false;
382 }
383 return write_network_geometry_buffer_gpu_sample(cache, stream_name, buffer, graphics_op);
384 }
385
386 std::vector<std::pair<std::string, Nodes::Network::GraphicsOperator*>> graphics_ops;
387 if (auto* primary = dynamic_cast<Nodes::Network::GraphicsOperator*>(network->get_operator())) {
388 graphics_ops.emplace_back(std::string(primary->get_type_name()), primary);
389 }
390 if (chain) {
391 for (const auto& op : chain->operators()) {
392 if (auto* secondary = dynamic_cast<Nodes::Network::GraphicsOperator*>(op.get())) {
393 graphics_ops.emplace_back(std::string(secondary->get_type_name()), secondary);
394 }
395 }
396 }
397
398 if (graphics_ops.empty()) {
399 MF_ERROR(Journal::Component::IO, Journal::Context::FileIO,
400 "write_network_geometry_buffer_sample: network has no GraphicsOperator");
401 return false;
402 }
403
404 if (graphics_ops.size() == 1) {
405 return write_operator_sample(cache, stream_name, graphics_ops.front().second);
406 }
407
408 std::unordered_map<std::string, int> seen;
409 for (const auto& [type_name, op] : graphics_ops) {
410 int& occurrence = seen[type_name];
411 std::string set_name = stream_name;
412 set_name.append("_").append(type_name);
413 if (occurrence != 0) {
414 set_name.append(std::to_string(occurrence));
415 }
416 ++occurrence;
417
418 if (!write_operator_sample(cache, set_name, op)) {
419 return false;
420 }
421 }
422
423 return true;
424}
#define MF_ERROR(comp, ctx,...)
Core::GlobalNetworkConfig network
Definition Config.cpp:39
std::shared_ptr< NetworkGeometryBuffer > buffer
BufferProcessingChain * chain
bool write_operator_sample(SpatialCache &cache, const std::string &stream_name, const Nodes::Network::GraphicsOperator *op)
Pack one GraphicsOperator's current vertex state into a SpatialCache stream, as a Points or Curves sa...
constexpr std::string_view type_name() noexcept
Returns the fully qualified compile-time type name of T.
Definition TypeInfo.hpp:28

References buffer, chain, MayaFlux::Journal::FileIO, MayaFlux::Journal::IO, MF_ERROR, network, and write_operator_sample().

Referenced by make_network_geometry_source().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: