Slicer  4.11
Slicer is a multi-platform, free and open source software package for visualization and medical image computing
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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