Slicer  5.2
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 #define vtkMRMLReadXMLStdStringVectorMacro(xmlAttributeName, propertyName, vectorType) \
330  if (!strcmp(xmlReadAttName, #xmlAttributeName)) \
331  { \
332  vectorType<std::string> attributeValues; \
333  std::string valueString(xmlReadAttValue); \
334  std::vector<std::string> splitXmlReadAttValue = vtksys::SystemTools::SplitString(valueString, ';'); \
335  for (std::string attributeValue : splitXmlReadAttValue) \
336  { \
337  vtksys::SystemTools::ReplaceString(attributeValue, "%3B", ";"); \
338  vtksys::SystemTools::ReplaceString(attributeValue, "%25", "%"); \
339  attributeValues.emplace_back(attributeValue); \
340  } \
341  this->Set##propertyName(attributeValues); \
342  }
343 
347 #define vtkMRMLReadXMLOwnedMatrix4x4Macro(xmlAttributeName, propertyName) \
348  if (!strcmp(xmlReadAttName, #xmlAttributeName)) \
349  { \
350  vtkNew<vtkMatrix4x4> matrix; \
351  std::stringstream ss; \
352  double val; \
353  ss << xmlReadAttValue; \
354  for (int row = 0; row < 4; row++) \
355  { \
356  for (int col = 0; col < 4; col++) \
357  { \
358  ss >> val; \
359  matrix->SetElement(row, col, val); \
360  } \
361  } \
362  this->Get##propertyName()->DeepCopy(matrix); \
363  }
364 
366 
367 //----------------------------------------------------------------------------
374 
377 #define vtkMRMLCopyBeginMacro(sourceNode) \
378  { \
379  vtkMRMLNode* copySourceNode = this->SafeDownCast(sourceNode); \
380  if (copySourceNode != nullptr) \
381  {
382 
384 #define vtkMRMLCopyEndMacro() \
385  } \
386  else \
387  { \
388  vtkErrorMacro("Copy failed: invalid source node"); \
389  } \
390  }
391 
393 #define vtkMRMLCopyBooleanMacro(propertyName) \
394  this->Set##propertyName(this->SafeDownCast(copySourceNode)->Get##propertyName());
395 
397 #define vtkMRMLCopyStringMacro(propertyName) \
398  this->Set##propertyName(this->SafeDownCast(copySourceNode)->Get##propertyName());
399 
401 #define vtkMRMLCopyStdStringMacro(propertyName) \
402  this->Set##propertyName(this->SafeDownCast(copySourceNode)->Get##propertyName());
403 
405 #define vtkMRMLCopyIntMacro(propertyName) \
406  this->Set##propertyName(this->SafeDownCast(copySourceNode)->Get##propertyName());
407 
409 #define vtkMRMLCopyEnumMacro(propertyName) \
410  this->Set##propertyName(this->SafeDownCast(copySourceNode)->Get##propertyName());
411 
413 #define vtkMRMLCopyFloatMacro(propertyName) \
414  this->Set##propertyName(this->SafeDownCast(copySourceNode)->Get##propertyName());
415 
417 #define vtkMRMLCopyVectorMacro(propertyName, vectorType, vectorSize) \
418  { \
419  /* Currently, vectorType and vectorSize is not essential, but in the future */ \
420  /* this information may be used more. */ \
421  vectorType* sourceVector = this->SafeDownCast(copySourceNode)->Get##propertyName(); \
422  if (sourceVector != nullptr) \
423  { \
424  this->Set##propertyName(sourceVector); \
425  } \
426  else \
427  { \
428  vtkErrorMacro("Failed to copy " #propertyName " attribute value: source node returned NULL"); \
429  } \
430  }
431 
433 #define vtkMRMLCopyStdFloatVectorMacro(propertyName) \
434  this->Set##propertyName(this->SafeDownCast(copySourceNode)->Get##propertyName());
435 
437 #define vtkMRMLCopyStdIntVectorMacro(propertyName) \
438  this->Set##propertyName(this->SafeDownCast(copySourceNode)->Get##propertyName());
439 
441 #define vtkMRMLCopyStdStringVectorMacro(propertyName) \
442  this->Set##propertyName(this->SafeDownCast(copySourceNode)->Get##propertyName());
443 
447 #define vtkMRMLCopyOwnedMatrix4x4Macro(propertyName) \
448  this->Get##propertyName()->DeepCopy(this->SafeDownCast(copySourceNode)->Get##propertyName());
449 
451 
452 //----------------------------------------------------------------------------
459 
463 #define vtkMRMLPrintBeginMacro(os, indent) \
464  { \
465  ostream& printOutputStream = os; \
466  vtkIndent printOutputIndent = indent;
467 
469 #define vtkMRMLPrintEndMacro() \
470  }
471 
473 #define vtkMRMLPrintBooleanMacro(propertyName) \
474  printOutputStream << printOutputIndent << #propertyName ": " << (this->Get##propertyName() ? "true" : "false") << "\n";
475 
477 #define vtkMRMLPrintStringMacro(propertyName) \
478  printOutputStream << printOutputIndent << #propertyName ": " << (this->Get##propertyName() != nullptr ? this->Get##propertyName() : "(none)") << "\n";
479 
481 #define vtkMRMLPrintStdStringMacro(propertyName) \
482  printOutputStream << printOutputIndent << #propertyName ": " << this->Get##propertyName() << "\n";
483 
485 #define vtkMRMLPrintEnumMacro(propertyName) \
486  printOutputStream << printOutputIndent << #propertyName ": " << (Get##propertyName##AsString(Get##propertyName())) << "\n";
487 
489 #define vtkMRMLPrintIntMacro(propertyName) \
490  printOutputStream << printOutputIndent << #propertyName ": " << this->Get##propertyName() << "\n";
491 
493 #define vtkMRMLPrintFloatMacro(propertyName) \
494  printOutputStream << printOutputIndent << #propertyName ": " << this->Get##propertyName() << "\n";
495 
498 #define vtkMRMLPrintVectorMacro(propertyName, vectorType, vectorSize) \
499  { \
500  printOutputStream << printOutputIndent << #propertyName ": ("; \
501  vectorType* vectorValue = this->Get##propertyName(); \
502  if (vectorValue) \
503  { \
504  for (int i=0; i<vectorSize; i++) \
505  { \
506  if (i > 0) \
507  { \
508  printOutputStream << ", "; \
509  } \
510  printOutputStream << vectorValue[i]; \
511  } \
512  printOutputStream << ")\n"; \
513  } \
514  }
515 
518 #define vtkMRMLPrintStdFloatVectorMacro(propertyName, vectorType) \
519  { \
520  printOutputStream << printOutputIndent << #propertyName " : ("; \
521  vectorType vector = this->Get##propertyName(); \
522  for (vectorType::iterator it=vector.begin(); it!=vector.end(); it++) \
523  { \
524  if (it != vector.begin()) \
525  { \
526  printOutputStream << ", "; \
527  } \
528  printOutputStream << *it; \
529  } \
530  printOutputStream << ")\n"; \
531  }
532 
535 #define vtkMRMLPrintStdIntVectorMacro(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 vtkMRMLPrintStdStringVectorMacro(propertyName, vectorType) \
552  { \
553  printOutputStream << printOutputIndent << #propertyName " : (\""; \
554  vectorType<std::string> vector = this->Get##propertyName(); \
555  for (vectorType<std::string>::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 
566 #define vtkMRMLPrintMatrix4x4Macro(propertyName) \
567  { \
568  vtkMatrix4x4* matrix = this->Get##propertyName(); \
569  printOutputStream << printOutputIndent << #propertyName ":"; \
570  if (matrix) \
571  { \
572  printOutputStream << "\n"; \
573  matrix->PrintSelf(printOutputStream, printOutputIndent.GetNextIndent()); \
574  } \
575  else \
576  { \
577  printOutputStream << " (none)\n"; \
578  } \
579  }
580 
581 #define vtkMRMLPrintObjectMacro(propertyName) \
582  { \
583  vtkObject* obj = this->Get##propertyName(); \
584  printOutputStream << printOutputIndent << #propertyName ":"; \
585  if (obj) \
586  { \
587  printOutputStream << "\n"; \
588  obj->PrintSelf(printOutputStream, printOutputIndent.GetNextIndent()); \
589  } \
590  else \
591  { \
592  printOutputStream << " (none)\n"; \
593  } \
594  }
595 
596 
598 
599 #endif // __vtkMRMLNodePropertyMacros_h