Slicer  5.0
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 #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 
497 #define vtkMRMLPrintVectorMacro(propertyName, vectorType, vectorSize) \
498  { \
499  printOutputStream << printOutputIndent << #propertyName ": ["; \
500  vectorType* vectorValue = this->Get##propertyName(); \
501  if (vectorValue) \
502  { \
503  for (int i=0; i<vectorSize; i++) \
504  { \
505  if (i > 0) \
506  { \
507  printOutputStream << ", "; \
508  } \
509  printOutputStream << vectorValue[i]; \
510  } \
511  printOutputStream << "]\n"; \
512  } \
513  }
514 
516 #define vtkMRMLPrintStdFloatVectorMacro(propertyName, vectorType) \
517  { \
518  printOutputStream << printOutputIndent << #propertyName " : ["; \
519  vectorType vector = this->Get##propertyName(); \
520  for (vectorType::iterator it=vector.begin(); it!=vector.end(); it++) \
521  { \
522  if (it != vector.begin()) \
523  { \
524  printOutputStream << ", "; \
525  } \
526  printOutputStream << *it; \
527  } \
528  printOutputStream << "]\n"; \
529  }
530 
532 #define vtkMRMLPrintStdIntVectorMacro(propertyName, vectorType) \
533  { \
534  printOutputStream << printOutputIndent << #propertyName " : ["; \
535  vectorType vector = this->Get##propertyName(); \
536  for (vectorType::iterator it=vector.begin(); it!=vector.end(); it++) \
537  { \
538  if (it != vector.begin()) \
539  { \
540  printOutputStream << ", "; \
541  } \
542  printOutputStream << *it; \
543  } \
544  printOutputStream << "]\n"; \
545  }
546 
548 #define vtkMRMLPrintStdStringVectorMacro(propertyName, vectorType) \
549  { \
550  printOutputStream << printOutputIndent << #propertyName " : ["; \
551  vectorType<std::string> vector = this->Get##propertyName(); \
552  for (vectorType<std::string>::iterator it=vector.begin(); it!=vector.end(); it++) \
553  { \
554  if (it != vector.begin()) \
555  { \
556  printOutputStream << ", "; \
557  } \
558  printOutputStream << *it; \
559  } \
560  printOutputStream << "]\n"; \
561  }
562 
563 #define vtkMRMLPrintMatrix4x4Macro(propertyName) \
564  { \
565  vtkMatrix4x4* matrix = this->Get##propertyName(); \
566  printOutputStream << printOutputIndent << #propertyName ":"; \
567  if (matrix) \
568  { \
569  printOutputStream << "\n"; \
570  matrix->PrintSelf(printOutputStream, printOutputIndent.GetNextIndent()); \
571  } \
572  else \
573  { \
574  printOutputStream << " (none)\n"; \
575  } \
576  }
577 
578 #define vtkMRMLPrintObjectMacro(propertyName) \
579  { \
580  vtkObject* obj = this->Get##propertyName(); \
581  printOutputStream << printOutputIndent << #propertyName ":"; \
582  if (obj) \
583  { \
584  printOutputStream << "\n"; \
585  obj->PrintSelf(printOutputStream, printOutputIndent.GetNextIndent()); \
586  } \
587  else \
588  { \
589  printOutputStream << " (none)\n"; \
590  } \
591  }
592 
593 
595 
596 #endif // __vtkMRMLNodePropertyMacros_h