134 this->
printMsg(
"Parsing vtkDataObject from JSON string", 0, 0,
140 boost::property_tree::ptree pt;
142 std::stringstream ss;
144 boost::property_tree::read_json(ss, pt);
145 }
catch(
const std::exception &e) {
146 this->
printErr(
"Unable to parse JSON message: " + json);
153 for(
auto it = pt.begin(); it != pt.end(); ++it) {
156 auto jsonVtkDataSet = it->second;
157 if(!jsonHasChild(jsonVtkDataSet,
"className")
158 || !jsonHasChild(jsonVtkDataSet,
"points")
159 || !jsonHasChild(jsonVtkDataSet,
"cells")
160 || !jsonHasChild(jsonVtkDataSet,
"pointData")
161 || !jsonHasChild(jsonVtkDataSet,
"cellData")
162 || !jsonHasChild(jsonVtkDataSet,
"fieldData")) {
163 this->
printErr(
"Invalid vtkDataSet serialization.");
167 if(jsonGetValue<std::string>(jsonVtkDataSet,
"className")
168 .compare(
"vtkUnstructuredGrid")
171 "Currently WebSocketIO only supports parsing 'vtkUnstructuredGrids'.");
178 = jsonGetValue<int>(jsonVtkDataSet,
"points.coordinates.nTuples");
182 points->SetNumberOfPoints(nPoints);
184 jsonArrayToArray<float>(jsonVtkDataSet,
"points.coordinates.data",
187 block->SetPoints(points);
193 constexpr int vtkCellsTypeHash[20] = {VTK_EMPTY_CELL,
198 VTK_CONVEX_POINT_SET,
199 VTK_CONVEX_POINT_SET,
200 VTK_CONVEX_POINT_SET,
202 VTK_CONVEX_POINT_SET,
203 VTK_CONVEX_POINT_SET,
204 VTK_CONVEX_POINT_SET,
205 VTK_CONVEX_POINT_SET,
206 VTK_CONVEX_POINT_SET,
207 VTK_CONVEX_POINT_SET,
208 VTK_CONVEX_POINT_SET,
209 VTK_CONVEX_POINT_SET,
210 VTK_CONVEX_POINT_SET,
211 VTK_CONVEX_POINT_SET,
212 VTK_CONVEX_POINT_SET};
215 = jsonGetValue<int>(jsonVtkDataSet,
"cells.offsetsArray.nTuples");
217 offsets->SetNumberOfTuples(nOffsets);
219 jsonArrayToArray<vtkIdType>(
220 jsonVtkDataSet,
"cells.offsetsArray.data", offsetsData);
223 = jsonGetValue<int>(jsonVtkDataSet,
"cells.connectivityArray.nTuples");
225 connectivity->SetNumberOfTuples(nConnectivity);
226 jsonArrayToArray<vtkIdType>(
227 jsonVtkDataSet,
"cells.connectivityArray.data",
231 cells->SetData(offsets, connectivity);
234 cellTypes->SetNumberOfTuples(nOffsets - 1);
236 for(
int i = 1; i < nOffsets; i++) {
238 = vtkCellsTypeHash[offsetsData[i] - offsetsData[i - 1]];
241 block->SetCells(cellTypes, cells);
244 auto addArraysToAssociation = [](vtkFieldData *fd,
245 const boost::property_tree::ptree &fdJSON,
246 const std::string &fdKey) {
248 for(
const auto &pda : fdJSON.get_child(fdKey)) {
249 const auto &jsonArray = pda.second;
250 size_t const nComponents
251 = jsonGetValue<size_t>(jsonArray,
"nComponents");
252 size_t const nTuples = jsonGetValue<size_t>(jsonArray,
"nTuples");
255 vtkDataArray::CreateArray(jsonGetValue<int>(jsonArray,
"dataType")));
257 array->SetName(jsonGetValue<std::string>(jsonArray,
"name").data());
258 array->SetNumberOfComponents(nComponents);
259 array->SetNumberOfTuples(nTuples);
261 if(
auto dataArray = vtkDataArray::SafeDownCast(array)) {
262 switch(dataArray->GetDataType()) {
263 vtkTemplateMacro(jsonArrayToArray<VTK_TT>(
267 }
else if(
auto stringArray = vtkStringArray::SafeDownCast(array)) {
268 std::vector<std::string> values;
270 jsonGetValue<std::string>(jsonArray,
"data"), values);
272 for(
size_t i = 0; i < values.size(); i++)
273 stringArray->SetValue(i, values[i]);
283 if(!addArraysToAssociation(
284 block->GetPointData(), jsonVtkDataSet,
"pointData")) {
285 this->
printErr(
"Unsupported data type.");
288 if(!addArraysToAssociation(
289 block->GetCellData(), jsonVtkDataSet,
"cellData")) {
290 this->
printErr(
"Unsupported data type.");
293 if(!addArraysToAssociation(
294 block->GetFieldData(), jsonVtkDataSet,
"fieldData")) {
295 this->
printErr(
"Unsupported data type.");
299 this->LastOutput->SetBlock(b++, block);
303 "Parsing vtkDataObject from JSON string", 1, timer.
getElapsedTime());
319 if(object->IsA(
"vtkMultiBlockDataSet"))
320 objectAsMB->ShallowCopy(
object);
322 objectAsMB->SetBlock(0,
object);
324 const size_t nBlocks = objectAsMB->GetNumberOfBlocks();
325 for(
size_t b = 0; b < nBlocks; b++) {
326 auto block = vtkDataSet::SafeDownCast(objectAsMB->GetBlock(b));
328 this->
printErr(
"Input `vtkDataObject` is not a `vtkDataSet` or a "
329 "`vtkMultiBlockDataSet` containing only `vtkDataSets`.");
335 + std::string(block->GetClassName()) +
"\" }");
341 if(block->IsA(
"vtkImageData")) {
342 auto lastInputAsID = vtkImageData::SafeDownCast(block);
346 lastInputAsID->GetDimensions(dimension);
347 lastInputAsID->GetOrigin(origin);
348 lastInputAsID->GetSpacing(spacing);
353 + std::to_string(dimension[0]) +
"," + std::to_string(dimension[1])
354 +
"," + std::to_string(dimension[2])
357 + std::to_string(origin[0]) +
"," + std::to_string(origin[1]) +
","
358 + std::to_string(origin[2])
361 + std::to_string(spacing[0]) +
"," + std::to_string(spacing[1]) +
","
362 + std::to_string(spacing[2])
371 auto blockAsPS = vtkPointSet::SafeDownCast(block);
372 if(blockAsPS !=
nullptr) {
373 auto points = blockAsPS->GetPoints();
376 "\"target\": \"points\","
377 "\"name\": \"coordinates\","
379 + std::to_string(points ? points->GetDataType() : VTK_FLOAT)
382 + std::to_string(blockAsPS->GetNumberOfPoints())
386 if(blockAsPS->GetNumberOfPoints() > 0 && points !=
nullptr)
387 switch(points->GetDataType()) {
389 blockAsPS->GetNumberOfPoints() *
sizeof(VTK_TT) * 3,
399 vtkCellArray *cells =
nullptr;
401 if(block->IsA(
"vtkUnstructuredGrid")) {
402 auto blockAsUG = vtkUnstructuredGrid::SafeDownCast(block);
403 if(blockAsUG !=
nullptr) {
404 cells = blockAsUG->GetCells();
406 }
else if(block->IsA(
"vtkPolyData")) {
407 auto blockAsPD = vtkPolyData::SafeDownCast(block);
408 if(blockAsPD !=
nullptr) {
409 cells = blockAsPD->GetPolys() ? blockAsPD->GetPolys()
410 : blockAsPD->GetLines();
416 auto connectivityArray = cells->GetConnectivityArray();
419 "\"target\": \"cells\","
420 "\"name\": \"connectivityArray\","
422 + std::to_string(VTK_ID_TYPE)
425 + std::to_string(connectivityArray->GetNumberOfTuples())
429 if(connectivityArray->GetNumberOfTuples() > 0)
431 connectivityArray->GetNumberOfTuples() *
sizeof(vtkIdType),
436 auto offsetsArray = cells->GetOffsetsArray();
438 "\"target\": \"cells\","
439 "\"name\": \"offsetsArray\","
441 + std::to_string(VTK_ID_TYPE)
444 + std::to_string(offsetsArray->GetNumberOfTuples())
448 if(offsetsArray->GetNumberOfTuples() > 0)
450 offsetsArray->GetNumberOfTuples() *
sizeof(vtkIdType),
461 std::vector<std::pair<std::string, vtkFieldData *>> attributes
462 = {{
"pointData", block->GetPointData()},
463 {
"cellData", block->GetCellData()},
464 {
"fieldData", block->GetFieldData()}};
466 for(
auto &attribute : attributes) {
467 size_t const nArrays = attribute.second->GetNumberOfArrays();
469 for(
size_t i = 0; i < nArrays; i++) {
470 auto array = attribute.second->GetAbstractArray(i);
472 if(array->IsA(
"vtkDataArray")) {
473 auto dataArray = vtkDataArray::SafeDownCast(array);
474 if(dataArray ==
nullptr) {
483 + std::string(dataArray->GetName())
486 + std::to_string(dataArray->GetDataType())
489 + std::to_string(dataArray->GetNumberOfTuples())
492 + std::to_string(dataArray->GetNumberOfComponents()) +
"}");
493 if(dataArray->GetNumberOfValues() > 0)
494 switch(dataArray->GetDataType()) {
496 dataArray->GetNumberOfValues() *
sizeof(VTK_TT),
499 }
else if(array->IsA(
"vtkStringArray")) {
500 auto stringArray = vtkStringArray::SafeDownCast(array);
502 values += stringArray->GetValue(0);
503 for(
int j = 1; j < stringArray->GetNumberOfValues(); j++)
504 values +=
"," + stringArray->GetValue(j);
512 + std::string(stringArray->GetName())
515 + std::to_string(stringArray->GetDataType())
518 + std::to_string(stringArray->GetNumberOfTuples())
521 + std::to_string(stringArray->GetNumberOfComponents())
524 + boost::replace_all_copy(values,
"\"",
"\\\"")