Slicer  4.11
Slicer is a multi-platform, free and open source software package for visualization and medical image computing
vtkMRMLNodePropertyMacros.h
Go to the documentation of this file.
1 /*=auto=========================================================================
2 
3  Portions (c) Copyright 2005 Brigham and Women's Hospital (BWH) All Rights Reserved.
4 
5  See COPYRIGHT.txt
6  or http://www.slicer.org/copyright/copyright.txt for details.
7 
8 =========================================================================auto=*/
9 
10 #ifndef __vtkMRMLNodePropertyMacros_h
11 #define __vtkMRMLNodePropertyMacros_h
12 
13 #include <sstream> // needed for std::stringstream
14 #include <vtksys/SystemTools.hxx> // needed for vtksys::SystemTools functions
15 
17 
18 //----------------------------------------------------------------------------
26 
29 #define vtkMRMLWriteXMLBeginMacro(of) \
30  { \
31  ostream& xmlWriteOutputStream = of;
32 
34 #define vtkMRMLWriteXMLEndMacro() \
35  }
36 
38 #define vtkMRMLWriteXMLBooleanMacro(xmlAttributeName, propertyName) \
39  xmlWriteOutputStream << " " #xmlAttributeName "=\"" << (Get##propertyName() ? "true" : "false") << "\"";
40 
43 #define vtkMRMLWriteXMLStringMacro(xmlAttributeName, propertyName) \
44  if (Get##propertyName() != nullptr) \
45  { \
46  xmlWriteOutputStream << " " #xmlAttributeName "=\""; \
47  xmlWriteOutputStream << vtkMRMLNode::XMLAttributeEncodeString(Get##propertyName()); \
48  xmlWriteOutputStream << "\""; \
49  }
50 
52 #define vtkMRMLWriteXMLStdStringMacro(xmlAttributeName, propertyName) \
53  xmlWriteOutputStream << " " #xmlAttributeName "=\"" << vtkMRMLNode::XMLAttributeEncodeString(Get##propertyName().c_str()) << "\""; \
54 
55 #define vtkMRMLWriteXMLEnumMacro(xmlAttributeName, propertyName) \
58  xmlWriteOutputStream << " " #xmlAttributeName "=\""; \
59  if (Get##propertyName##AsString(Get##propertyName()) != nullptr) \
60  { \
61  xmlWriteOutputStream << vtkMRMLNode::XMLAttributeEncodeString(Get##propertyName##AsString(Get##propertyName())); \
62  } \
63  xmlWriteOutputStream << "\"";
64 
66 #define vtkMRMLWriteXMLIntMacro(xmlAttributeName, propertyName) \
67  xmlWriteOutputStream << " " #xmlAttributeName "=\"" << Get##propertyName() << "\"";
68 
70 #define vtkMRMLWriteXMLFloatMacro(xmlAttributeName, propertyName) \
71  xmlWriteOutputStream << " " #xmlAttributeName "=\"" << Get##propertyName() << "\"";
72 
74 #define vtkMRMLWriteXMLVectorMacro(xmlAttributeName, propertyName, vectorType, vectorSize) \
75  { \
76  xmlWriteOutputStream << " " #xmlAttributeName "=\""; \
77  vectorType* vectorPtr = Get##propertyName(); \
78  if (vectorPtr != nullptr) \
79  { \
80  for (int i=0; i<vectorSize; i++) \
81  { \
82  if (i > 0) \
83  { \
84  xmlWriteOutputStream << " "; \
85  } \
86  xmlWriteOutputStream << vectorPtr[i]; \
87  } \
88  } \
89  xmlWriteOutputStream << "\""; \
90  }
91 
93 #define vtkMRMLWriteXMLStdFloatVectorMacro(xmlAttributeName, propertyName, vectorType) \
94  { \
95  xmlWriteOutputStream << " " #xmlAttributeName "=\""; \
96  vectorType vector = Get##propertyName(); \
97  for (vectorType::iterator it=vector.begin(); it!=vector.end(); it++) \
98  { \
99  xmlWriteOutputStream << *it; \
100  xmlWriteOutputStream << " "; \
101  } \
102  xmlWriteOutputStream << "\""; \
103  }
104 
106 #define vtkMRMLWriteXMLStdIntVectorMacro(xmlAttributeName, propertyName, vectorType) \
107  { \
108  xmlWriteOutputStream << " " #xmlAttributeName "=\""; \
109  vectorType vector = Get##propertyName(); \
110  for (vectorType::iterator it=vector.begin(); it!=vector.end(); it++) \
111  { \
112  xmlWriteOutputStream << *it; \
113  xmlWriteOutputStream << " "; \
114  } \
115  xmlWriteOutputStream << "\""; \
116  }
117 
119 #define vtkMRMLWriteXMLStdStringVectorMacro(xmlAttributeName, propertyName, vectorType) \
120  { \
121  xmlWriteOutputStream << " " #xmlAttributeName "=\""; \
122  vectorType<std::string> vector = Get##propertyName(); \
123  for (vectorType<std::string>::iterator it=vector.begin(); it!=vector.end(); it++) \
124  { \
125  if (it!=vector.begin()) \
126  { \
127  xmlWriteOutputStream << ";"; \
128  } \
129  std::string attributeValue = *it; \
130  vtksys::SystemTools::ReplaceString(attributeValue, "%", "%25"); \
131  vtksys::SystemTools::ReplaceString(attributeValue, ";", "%3B"); \
132  xmlWriteOutputStream << vtkMRMLNode::XMLAttributeEncodeString(attributeValue); \
133  } \
134  xmlWriteOutputStream << "\""; \
135  }
136 
137 
139 #define vtkMRMLWriteXMLMatrix4x4Macro(xmlAttributeName, propertyName) \
140  { \
141  xmlWriteOutputStream << " " #xmlAttributeName "=\""; \
142  vtkMatrix4x4* matrix = this->Get##propertyName(); \
143  for (int row = 0; row < 4; row++) \
144  { \
145  for (int col = 0; col < 4; col++) \
146  { \
147  of << matrix->GetElement(row, col); \
148  if (!(row == 3 && col == 3)) \
149  { \
150  of << " "; \
151  } \
152  } \
153  if (row != 3) \
154  { \
155  of << " "; \
156  } \
157  } \
158  xmlWriteOutputStream << "\""; \
159  }
160 
162 
163 //----------------------------------------------------------------------------
171 
174 #define vtkMRMLReadXMLBeginMacro(atts) \
175  { \
176  const char* xmlReadAttName; \
177  const char* xmlReadAttValue; \
178  const char** xmlReadAtts = atts; \
179  while (*xmlReadAtts != nullptr) \
180  { \
181  xmlReadAttName = *(xmlReadAtts++); \
182  xmlReadAttValue = *(xmlReadAtts++); \
183  if (xmlReadAttValue == nullptr) \
184  { \
185  break; \
186  }
187 
189 #define vtkMRMLReadXMLEndMacro() \
190  }};
191 
193 #define vtkMRMLReadXMLBooleanMacro(xmlAttributeName, propertyName) \
194  if (!strcmp(xmlReadAttName, #xmlAttributeName)) \
195  { \
196  this->Set##propertyName(strcmp(xmlReadAttValue,"true") ? false : true); \
197  }
198 
201 #define vtkMRMLReadXMLStringMacro(xmlAttributeName, propertyName) \
202  if (!strcmp(xmlReadAttName, #xmlAttributeName)) \
203  { \
204  this->Set##propertyName(xmlReadAttValue); \
205  }
206 
209 #define vtkMRMLReadXMLStdStringMacro(xmlAttributeName, propertyName) \
210  if (!strcmp(xmlReadAttName, #xmlAttributeName)) \
211  { \
212  this->Set##propertyName(xmlReadAttValue); \
213  }
214 
218 #define vtkMRMLReadXMLEnumMacro(xmlAttributeName, propertyName) \
219  if (!strcmp(xmlReadAttName, #xmlAttributeName)) \
220  { \
221  int propertyValue = this->Get##propertyName##FromString(xmlReadAttValue); \
222  if (propertyValue >= 0) \
223  { \
224  this->Set##propertyName(propertyValue); \
225  } \
226  else \
227  { \
228  vtkErrorMacro("Failed to read #xmlAttributeName attribute value from string '" << xmlReadAttValue << "'"); \
229  } \
230  }
231 
233 #define vtkMRMLReadXMLIntMacro(xmlAttributeName, propertyName) \
234  if (!strcmp(xmlReadAttName, #xmlAttributeName)) \
235  { \
236  vtkVariant variantValue(xmlReadAttValue); \
237  bool valid = false; \
238  int intValue = variantValue.ToInt(&valid); \
239  if (valid) \
240  { \
241  this->Set##propertyName(intValue); \
242  } \
243  else \
244  { \
245  vtkErrorMacro("Failed to read #xmlAttributeName attribute value from string '" << xmlReadAttValue << "': integer expected"); \
246  } \
247  }
248 
250 #define vtkMRMLReadXMLFloatMacro(xmlAttributeName, propertyName) \
251  if (!strcmp(xmlReadAttName, #xmlAttributeName)) \
252  { \
253  vtkVariant variantValue(xmlReadAttValue); \
254  bool valid = false; \
255  double scalarValue = variantValue.ToDouble(&valid); \
256  if (valid) \
257  { \
258  this->Set##propertyName(scalarValue); \
259  } \
260  else \
261  { \
262  vtkErrorMacro("Failed to read #xmlAttributeName attribute value from string '" << xmlReadAttValue << "': float expected"); \
263  } \
264  }
265 
267 #define vtkMRMLReadXMLVectorMacro(xmlAttributeName, propertyName, vectorType, vectorSize) \
268  if (!strcmp(xmlReadAttName, #xmlAttributeName)) \
269  { \
270  vectorType vectorValue[vectorSize] = {0}; \
271  std::stringstream ss; \
272  ss << xmlReadAttValue; \
273  for (int i=0; i<vectorSize; i++) \
274  { \
275  vectorType val; \
276  ss >> val; \
277  vectorValue[i] = val; \
278  } \
279  this->Set##propertyName(vectorValue); \
280  }
281 
283 #define vtkMRMLReadXMLStdFloatVectorMacro(xmlAttributeName, propertyName, vectorType) \
284  if (!strcmp(xmlReadAttName, #xmlAttributeName)) \
285  { \
286  vectorType vector; \
287  std::string valueString(xmlReadAttValue); \
288  size_t separatorPosition = valueString.find(" "); \
289  while(separatorPosition != std::string::npos) \
290  { \
291  std::string attributeValue = valueString.substr(0, separatorPosition); \
292  vtkVariant variantValue(attributeValue); \
293  bool valid = false; \
294  vectorType::value_type scalarValue = variantValue.ToDouble(&valid); \
295  if (valid) \
296  { \
297  vector.insert(vector.end(), scalarValue); \
298  } \
299  valueString = valueString.substr(separatorPosition+1); \
300  separatorPosition = valueString.find(" "); \
301  } \
302  this->Set##propertyName(vector); \
303  }
304 
306 #define vtkMRMLReadXMLStdIntVectorMacro(xmlAttributeName, propertyName, vectorType) \
307  if (!strcmp(xmlReadAttName, #xmlAttributeName)) \
308  { \
309  vectorType vector; \
310  std::string valueString(xmlReadAttValue); \
311  size_t separatorPosition = valueString.find(" "); \
312  while(separatorPosition != std::string::npos) \
313  { \
314  std::string attributeValue = valueString.substr(0, separatorPosition); \
315  vtkVariant variantValue(attributeValue); \
316  bool valid = false; \
317  vectorType::value_type scalarValue = variantValue.ToInt(&valid); \
318  if (valid) \
319  { \
320  vector.insert(vector.end(), scalarValue); \
321  } \
322  valueString = valueString.substr(separatorPosition+1); \
323  separatorPosition = valueString.find(" "); \
324  } \
325  this->Set##propertyName(vector); \
326  }
327 
329 #if VTK_MAJOR_VERSION >= 9 || (VTK_MAJOR_VERSION >= 8 && VTK_MINOR_VERSION >= 90)
330 // Use std::string
331 #define vtkMRMLReadXMLStdStringVectorMacro(xmlAttributeName, propertyName, vectorType) \
332  if (!strcmp(xmlReadAttName, #xmlAttributeName)) \
333  { \
334  vectorType<std::string> attributeValues; \
335  std::string valueString(xmlReadAttValue); \
336  std::vector<std::string> splitXmlReadAttValue = vtksys::SystemTools::SplitString(valueString, ';'); \
337  for (std::string attributeValue : splitXmlReadAttValue) \
338  { \
339  vtksys::SystemTools::ReplaceString(attributeValue, "%3B", ";"); \
340  vtksys::SystemTools::ReplaceString(attributeValue, "%25", "%"); \
341  attributeValues.emplace_back(attributeValue); \
342  } \
343  this->Set##propertyName(attributeValues); \
344  }
345 #else
346 // Use vtksys::String
347 #define vtkMRMLReadXMLStdStringVectorMacro(xmlAttributeName, propertyName, vectorType) \
348  if (!strcmp(xmlReadAttName, #xmlAttributeName)) \
349  { \
350  vectorType<std::string> attributeValues; \
351  std::string valueString(xmlReadAttValue); \
352  std::vector<vtksys::String> splitXmlReadAttValue = vtksys::SystemTools::SplitString(valueString, ';'); \
353  for (std::string attributeValue : splitXmlReadAttValue) \
354  { \
355  vtksys::SystemTools::ReplaceString(attributeValue, "%3B", ";"); \
356  vtksys::SystemTools::ReplaceString(attributeValue, "%25", "%"); \
357  attributeValues.emplace_back(attributeValue); \
358  } \
359  this->Set##propertyName(attributeValues); \
360  }
361 #endif
362 
366 #define vtkMRMLReadXMLOwnedMatrix4x4Macro(xmlAttributeName, propertyName) \
367  if (!strcmp(xmlReadAttName, #xmlAttributeName)) \
368  { \
369  vtkNew<vtkMatrix4x4> matrix; \
370  std::stringstream ss; \
371  double val; \
372  ss << xmlReadAttValue; \
373  for (int row = 0; row < 4; row++) \
374  { \
375  for (int col = 0; col < 4; col++) \
376  { \
377  ss >> val; \
378  matrix->SetElement(row, col, val); \
379  } \
380  } \
381  this->Get##propertyName()->DeepCopy(matrix); \
382  }
383 
385 
386 //----------------------------------------------------------------------------
393 
396 #define vtkMRMLCopyBeginMacro(sourceNode) \
397  { \
398  vtkMRMLNode* copySourceNode = this->SafeDownCast(sourceNode); \
399  if (copySourceNode != nullptr) \
400  {
401 
403 #define vtkMRMLCopyEndMacro() \
404  } \
405  else \
406  { \
407  vtkErrorMacro("Copy failed: invalid source node"); \
408  } \
409  }
410 
412 #define vtkMRMLCopyBooleanMacro(propertyName) \
413  this->Set##propertyName(this->SafeDownCast(copySourceNode)->Get##propertyName());
414 
416 #define vtkMRMLCopyStringMacro(propertyName) \
417  this->Set##propertyName(this->SafeDownCast(copySourceNode)->Get##propertyName());
418 
420 #define vtkMRMLCopyStdStringMacro(propertyName) \
421  this->Set##propertyName(this->SafeDownCast(copySourceNode)->Get##propertyName());
422 
424 #define vtkMRMLCopyIntMacro(propertyName) \
425  this->Set##propertyName(this->SafeDownCast(copySourceNode)->Get##propertyName());
426 
428 #define vtkMRMLCopyEnumMacro(propertyName) \
429  this->Set##propertyName(this->SafeDownCast(copySourceNode)->Get##propertyName());
430 
432 #define vtkMRMLCopyFloatMacro(propertyName) \
433  this->Set##propertyName(this->SafeDownCast(copySourceNode)->Get##propertyName());
434 
436 #define vtkMRMLCopyVectorMacro(propertyName, vectorType, vectorSize) \
437  { \
438  /* Currently, vectorType and vectorSize is not essential, but in the future */ \
439  /* this information may be used more. */ \
440  vectorType* sourceVector = this->SafeDownCast(copySourceNode)->Get##propertyName(); \
441  if (sourceVector != nullptr) \
442  { \
443  this->Set##propertyName(sourceVector); \
444  } \
445  else \
446  { \
447  vtkErrorMacro("Failed to copy #xmlAttributeName attribute value: source node returned NULL"); \
448  } \
449  }
450 
452 #define vtkMRMLCopyStdFloatVectorMacro(propertyName) \
453  this->Set##propertyName(this->SafeDownCast(copySourceNode)->Get##propertyName());
454 
456 #define vtkMRMLCopyStdIntVectorMacro(propertyName) \
457  this->Set##propertyName(this->SafeDownCast(copySourceNode)->Get##propertyName());
458 
460 #define vtkMRMLCopyStdStringVectorMacro(propertyName) \
461  this->Set##propertyName(this->SafeDownCast(copySourceNode)->Get##propertyName());
462 
466 #define vtkMRMLCopyOwnedMatrix4x4Macro(propertyName) \
467  this->Get##propertyName()->DeepCopy(this->SafeDownCast(copySourceNode)->Get##propertyName());
468 
470 
471 //----------------------------------------------------------------------------
478 
482 #define vtkMRMLPrintBeginMacro(os, indent) \
483  { \
484  ostream& printOutputStream = os; \
485  vtkIndent printOutputIndent = indent;
486 
488 #define vtkMRMLPrintEndMacro() \
489  }
490 
492 #define vtkMRMLPrintBooleanMacro(propertyName) \
493  printOutputStream << printOutputIndent << #propertyName ": " << (this->Get##propertyName() ? "true" : "false") << "\n";
494 
496 #define vtkMRMLPrintStringMacro(propertyName) \
497  printOutputStream << printOutputIndent << #propertyName ": " << (this->Get##propertyName() != nullptr ? this->Get##propertyName() : "(none)") << "\n";
498 
500 #define vtkMRMLPrintStdStringMacro(propertyName) \
501  printOutputStream << printOutputIndent << #propertyName ": " << this->Get##propertyName() << "\n";
502 
504 #define vtkMRMLPrintEnumMacro(propertyName) \
505  printOutputStream << printOutputIndent << #propertyName ": " << (Get##propertyName##AsString(Get##propertyName())) << "\n";
506 
508 #define vtkMRMLPrintIntMacro(propertyName) \
509  printOutputStream << printOutputIndent << #propertyName ": " << this->Get##propertyName() << "\n";
510 
512 #define vtkMRMLPrintFloatMacro(propertyName) \
513  printOutputStream << printOutputIndent << #propertyName ": " << this->Get##propertyName() << "\n";
514 
516 #define vtkMRMLPrintVectorMacro(propertyName, vectorType, vectorSize) \
517  { \
518  printOutputStream << printOutputIndent << #propertyName " : ["; \
519  vectorType* vectorValue = this->Get##propertyName(); \
520  if (vectorValue) \
521  { \
522  for (int i=0; i<vectorSize; i++) \
523  { \
524  if (i > 0) \
525  { \
526  printOutputStream << ", "; \
527  } \
528  printOutputStream << vectorValue[i]; \
529  } \
530  printOutputStream << "]\n"; \
531  } \
532  }
533 
535 #define vtkMRMLPrintStdFloatVectorMacro(propertyName, vectorType) \
536  { \
537  printOutputStream << printOutputIndent << #propertyName " : ["; \
538  vectorType vector = this->Get##propertyName(); \
539  for (vectorType::iterator it=vector.begin(); it!=vector.end(); it++) \
540  { \
541  if (it != vector.begin()) \
542  { \
543  printOutputStream << ", "; \
544  } \
545  printOutputStream << *it; \
546  } \
547  printOutputStream << "]\n"; \
548  }
549 
551 #define vtkMRMLPrintStdIntVectorMacro(propertyName, vectorType) \
552  { \
553  printOutputStream << printOutputIndent << #propertyName " : ["; \
554  vectorType vector = this->Get##propertyName(); \
555  for (vectorType::iterator it=vector.begin(); it!=vector.end(); it++) \
556  { \
557  if (it != vector.begin()) \
558  { \
559  printOutputStream << ", "; \
560  } \
561  printOutputStream << *it; \
562  } \
563  printOutputStream << "]\n"; \
564  }
565 
567 #define vtkMRMLPrintStdStringVectorMacro(propertyName, vectorType) \
568  { \
569  printOutputStream << printOutputIndent << #propertyName " : ["; \
570  vectorType<std::string> vector = this->Get##propertyName(); \
571  for (vectorType<std::string>::iterator it=vector.begin(); it!=vector.end(); it++) \
572  { \
573  if (it != vector.begin()) \
574  { \
575  printOutputStream << ", "; \
576  } \
577  printOutputStream << *it; \
578  } \
579  printOutputStream << "]\n"; \
580  }
581 
582 #define vtkMRMLPrintMatrix4x4Macro(propertyName) \
583  { \
584  vtkMatrix4x4* matrix = this->Get##propertyName(); \
585  printOutputStream << printOutputIndent << #propertyName ":"; \
586  if (matrix) \
587  { \
588  printOutputStream << "\n"; \
589  matrix->PrintSelf(printOutputStream, printOutputIndent.GetNextIndent()); \
590  } \
591  else \
592  { \
593  printOutputStream << " (none)\n"; \
594  } \
595  }
596 
597 #define vtkMRMLPrintObjectMacro(propertyName) \
598  { \
599  vtkObject* obj = this->Get##propertyName(); \
600  printOutputStream << printOutputIndent << #propertyName ":"; \
601  if (obj) \
602  { \
603  printOutputStream << "\n"; \
604  obj->PrintSelf(printOutputStream, printOutputIndent.GetNextIndent()); \
605  } \
606  else \
607  { \
608  printOutputStream << " (none)\n"; \
609  } \
610  }
611 
612 
614 
615 #endif // __vtkMRMLNodePropertyMacros_h