// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // SPDX-License-Identifier: BSD-3-Clause #include "vtkDataObject.h" #include "vtkDataSetAttributes.h" #include "vtkDeserializer.h" #include "vtkGraph.h" #include "vtkGraphInternals.h" #include "vtkInformation.h" #include "vtkPoints.h" #include "vtkSerializer.h" // clang-format off #include "vtk_nlohmannjson.h" #include #include VTK_NLOHMANN_JSON(json.hpp) // clang-format on extern "C" { /** * Register the (de)serialization handlers of vtkGraph * @param ser a vtkSerializer instance * @param deser a vtkDeserializer instance */ int RegisterHandlers_vtkGraphSerDesHelper(void* ser, void* deser, void* invoker); } static nlohmann::json Serialize_vtkGraph(vtkObjectBase* object, vtkSerializer* serializer) { using json = nlohmann::json; if (auto* graph = vtkGraph::SafeDownCast(object)) { json state; if (auto superSerializer = serializer->GetHandler(typeid(vtkGraph::Superclass))) { state = superSerializer(object, serializer); } state["SuperClassNames"].push_back("vtkObject"); { auto value = graph->GetVertexData(); if (value) { state["VertexData"] = serializer->SerializeJSON(reinterpret_cast(value)); } } { auto value = graph->GetEdgeData(); if (value) { state["EdgeData"] = serializer->SerializeJSON(reinterpret_cast(value)); } } { auto value = graph->GetPoints(); if (value) { state["Points"] = serializer->SerializeJSON(reinterpret_cast(value)); } } vtkGraphInternals* internals = graph->GetGraphInternals(false); auto& graphInternalState = state["InternalAdjacency"] = json::array(); for (const auto& adj : internals->Adjacency) { json adjListState; auto& inEdgesState = adjListState["InEdges"] = json::array(); auto& outEdgesState = adjListState["OutEdges"] = json::array(); for (const auto& inEdge : adj.InEdges) { inEdgesState.push_back({ inEdge.Id, inEdge.Source }); } for (const auto& outEdge : adj.OutEdges) { outEdgesState.push_back({ outEdge.Id, outEdge.Target }); } graphInternalState.push_back(adjListState); } state["NumberOfEdges"] = internals->NumberOfEdges; state["UsingPedigreeIds"] = internals->UsingPedigreeIds; return state; } else { return {}; } } static void Deserialize_vtkGraph( const nlohmann::json& state, vtkObjectBase* object, vtkDeserializer* deserializer) { auto* graph = vtkGraph::SafeDownCast(object); if (!graph) { return; } if (auto superDeserializer = deserializer->GetHandler(typeid(vtkGraph::Superclass))) { superDeserializer(state, object, deserializer); } vtkGraphInternals* internals = graph->GetGraphInternals(true); std::vector adjacency; for (const auto& adj : state["InternalAdjacency"]) { vtkVertexAdjacencyList adjList; for (const auto& edge : adj["InEdges"]) { adjList.InEdges.emplace_back(edge[1], edge[0]); } for (const auto& edge : adj["OutEdges"]) { adjList.OutEdges.emplace_back(edge[1], edge[0]); } adjacency.push_back(adjList); } internals->Adjacency = adjacency; internals->NumberOfEdges = state["NumberOfEdges"]; internals->UsingPedigreeIds = state["UsingPedigreeIds"]; { auto iter = state.find("VertexData"); if ((iter != state.end()) && !iter->is_null()) { auto* context = deserializer->GetContext(); const auto identifier = iter->at("Id").get(); vtkSmartPointer subObject = reinterpret_cast(graph->GetVertexData()); if (subObject == nullptr) { vtkErrorWithObjectMacro(context, << "An internal collection object is null!"); } else { if (context->GetObjectAtId(identifier) != subObject) { auto registrationId = identifier; context->RegisterObject(subObject, registrationId); } deserializer->DeserializeJSON(identifier, subObject); } } } { auto iter = state.find("EdgeData"); if ((iter != state.end()) && !iter->is_null()) { auto* context = deserializer->GetContext(); const auto identifier = iter->at("Id").get(); vtkSmartPointer subObject = reinterpret_cast(graph->GetEdgeData()); if (subObject == nullptr) { vtkErrorWithObjectMacro(context, << "An internal collection object is null!"); } else { if (context->GetObjectAtId(identifier) != subObject) { auto registrationId = identifier; context->RegisterObject(subObject, registrationId); } deserializer->DeserializeJSON(identifier, subObject); } } } VTK_DESERIALIZE_VTK_OBJECT_FROM_STATE(Points, vtkPoints, state, graph, deserializer); } int RegisterHandlers_vtkGraphSerDesHelper(void* ser, void* deser, void* vtkNotUsed(invoker)) { int success = 0; if (auto* asObjectBase = static_cast(ser)) { if (auto* serializer = vtkSerializer::SafeDownCast(asObjectBase)) { serializer->RegisterHandler(typeid(vtkGraph), Serialize_vtkGraph); success = 1; } } if (auto* asObjectBase = static_cast(deser)) { if (auto* deserializer = vtkDeserializer::SafeDownCast(asObjectBase)) { deserializer->RegisterHandler(typeid(vtkGraph), Deserialize_vtkGraph); deserializer->RegisterConstructor("vtkGraph", vtkGraph::New); success = 1; } } return success; }