VTK  9.3.0
WidgetTestingMacros.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2 // SPDX-License-Identifier: BSD-3-Clause
3 #ifndef vtkWidgetTestingMacros_h
4 #define vtkWidgetTestingMacros_h
5 
6 #include "vtkCamera.h"
7 #include "vtkDebugLeaks.h"
8 #include "vtkMath.h"
9 #include "vtkRenderWindow.h"
11 #include "vtkRenderer.h"
12 #include "vtkSmartPointer.h"
13 #include <vtkAbstractTransform.h>
14 #include <vtkActor.h>
15 #include <vtkAssemblyPath.h>
16 #include <vtkFollower.h>
17 #include <vtkInformation.h>
18 #include <vtkLineWidget2.h>
19 #include <vtkMatrix4x4.h>
21 #include <vtkPointPlacer.h>
22 #include <vtkPolyData.h>
23 #include <vtkProp.h>
24 #include <vtkPropCollection.h>
25 #include <vtkProperty.h>
26 #include <vtkProperty2D.h>
27 
29 #define EXERCISE_BASIC_OBJECT_METHODS(object) \
30  do \
31  { \
32  if (object == nullptr) \
33  { \
34  std::cerr << "EXERCISE_BASIC_OBJECT_METHODS( with nullptr object )" << std::endl; \
35  return EXIT_FAILURE; \
36  } \
37  object->Print(std::cout); \
38  std::cout << "Name of Class = " << object->GetClassName() << std::endl; \
39  std::cout << "Name of Superclass = " << object->Superclass::GetClassName() << std::endl; \
40  } while (false)
41 
43 #define TEST_SET_GET_BOOLEAN(object, variable) \
44  do \
45  { \
46  object->Set##variable(false); \
47  object->Set##variable(true); \
48  if (object->Get##variable() != 1) \
49  { \
50  std::cerr << "Error in Set/Get" #variable << ", Get" #variable << " is " \
51  << object->Get##variable() << " instead of 1" << std::endl; \
52  return EXIT_FAILURE; \
53  } \
54  object->Set##variable(false); \
55  if (object->Get##variable() != 0) \
56  { \
57  std::cerr << "Error in Set/Get" #variable << ", Get" #variable << " is " \
58  << object->Get##variable() << " instead of 0" << std::endl; \
59  return EXIT_FAILURE; \
60  } \
61  object->variable##On(); \
62  if (object->Get##variable() != 1) \
63  { \
64  std::cerr << "Error in On/Get" #variable << ", Get" #variable << " is " \
65  << object->Get##variable() << " instead of 1" << std::endl; \
66  return EXIT_FAILURE; \
67  } \
68  object->variable##Off(); \
69  if (object->Get##variable() != 0) \
70  { \
71  std::cerr << "Error in Off/Get" #variable << ", Get" #variable << " is " \
72  << object->Get##variable() << " instead of 0" << std::endl; \
73  return EXIT_FAILURE; \
74  } \
75  } while (false)
76 
79 #define TEST_SET_GET_INT(object, variable, value) \
80  do \
81  { \
82  object->Set##variable(value); \
83  if (object->Get##variable() != value) \
84  { \
85  std::cerr << "Error in Set/Get" #variable << " using value " << value << std::endl; \
86  return EXIT_FAILURE; \
87  } \
88  } while (false)
89 
94 #define TEST_SET_GET_INT_RANGE(object, variable, min, max) \
95  do \
96  { \
97  int epsilon = 1; \
98  int val = min - epsilon; \
99  TEST_SET_GET_INT(object, variable, val); \
100  val = min; \
101  TEST_SET_GET_INT(object, variable, val); \
102  val = min + epsilon; \
103  TEST_SET_GET_INT(object, variable, val); \
104  val = (min + max) / 2; \
105  TEST_SET_GET_INT(object, variable, val); \
106  val = max - epsilon; \
107  TEST_SET_GET_INT(object, variable, val); \
108  val = max; \
109  TEST_SET_GET_INT(object, variable, val); \
110  val = max + epsilon; \
111  TEST_SET_GET_INT(object, variable, val); \
112  } while (false)
113 
116 #define TEST_SET_GET_DOUBLE(object, variable, value) \
117  do \
118  { \
119  object->Set##variable(value); \
120  if (object->Get##variable() != value) \
121  { \
122  std::cerr << "Error in Set/Get" #variable << " using value '" << value << "', got '" \
123  << object->Get##variable() << "'" << std::endl; \
124  return EXIT_FAILURE; \
125  } \
126  } while (false)
127 
132 #define TEST_SET_GET_DOUBLE_RANGE(object, variable, min, max) \
133  do \
134  { \
135  double epsilon = 1.0; \
136  double val = min - epsilon; \
137  TEST_SET_GET_DOUBLE(object, variable, val); \
138  val = min; \
139  TEST_SET_GET_DOUBLE(object, variable, val); \
140  val = min + epsilon; \
141  TEST_SET_GET_DOUBLE(object, variable, val); \
142  val = (min + max) / 2.0; \
143  TEST_SET_GET_DOUBLE(object, variable, val); \
144  val = max - epsilon; \
145  TEST_SET_GET_DOUBLE(object, variable, val); \
146  val = max; \
147  TEST_SET_GET_DOUBLE(object, variable, val); \
148  val = max + epsilon; \
149  TEST_SET_GET_DOUBLE(object, variable, val); \
150  } while (false)
151 
154 #define TEST_SET_GET_VECTOR3_DOUBLE(object, variable, x, y, z) \
155  do \
156  { \
157  object->Set##variable(x, y, z); \
158  double* val = object->Get##variable(); \
159  if (val == nullptr || val[0] != x || val[1] != y || val[2] != z) \
160  { \
161  std::cerr << "Error in Set/Get" #variable << std::endl; \
162  return EXIT_FAILURE; \
163  } \
164  } while (false)
165 
168 #define TEST_SET_GET_VECTOR2(object, variable, x, y) \
169  do \
170  { \
171  object->Set##variable(x, y); \
172  int* val = object->Get##variable(); \
173  if (val == nullptr || val[0] != x || val[1] != y) \
174  { \
175  std::cerr << "Error in Set/Get" #variable << std::endl; \
176  return EXIT_FAILURE; \
177  } \
178  } while (false)
179 
185 #define TEST_SET_GET_VECTOR2_INT_RANGE(object, variable, min, max) \
186  do \
187  { \
188  int epsilon = 1; \
189  TEST_SET_GET_VECTOR2(object, variable, min - epsilon, min - epsilon); \
190  TEST_SET_GET_VECTOR2(object, variable, min, min); \
191  TEST_SET_GET_VECTOR2(object, variable, min + epsilon, min + epsilon); \
192  int half = (min + max / 2); \
193  TEST_SET_GET_VECTOR2(object, variable, half, half); \
194  TEST_SET_GET_VECTOR2(object, variable, max - epsilon, max - epsilon); \
195  TEST_SET_GET_VECTOR2(object, variable, max, max); \
196  TEST_SET_GET_VECTOR2(object, variable, max + epsilon, max + epsilon); \
197  } while (false)
198 
204 #define TEST_SET_GET_VECTOR2_DOUBLE_RANGE(object, variable, min, max) \
205  do \
206  { \
207  double epsilon = 1.0; \
208  TEST_SET_GET_VECTOR2(object, variable, min - epsilon, min - epsilon); \
209  TEST_SET_GET_VECTOR2(object, variable, min, min); \
210  TEST_SET_GET_VECTOR2(object, variable, min + epsilon, min + epsilon); \
211  double half = (min + max / 2.0); \
212  TEST_SET_GET_VECTOR2(object, variable, half, half); \
213  TEST_SET_GET_VECTOR2(object, variable, max - epsilon, max - epsilon); \
214  TEST_SET_GET_VECTOR2(object, variable, max, max); \
215  TEST_SET_GET_VECTOR2(object, variable, max + epsilon, max + epsilon); \
216  } while (false)
217 
223 #define TEST_SET_GET_VECTOR3_DOUBLE_RANGE(object, variable, min, max) \
224  do \
225  { \
226  double epsilon = 1.0; \
227  TEST_SET_GET_VECTOR3_DOUBLE(object, variable, min - epsilon, min - epsilon, min - epsilon); \
228  TEST_SET_GET_VECTOR3_DOUBLE(object, variable, min, min, min); \
229  TEST_SET_GET_VECTOR3_DOUBLE(object, variable, min + epsilon, min + epsilon, min + epsilon); \
230  double half = (min + max / 2.0); \
231  TEST_SET_GET_VECTOR3_DOUBLE(object, variable, half, half, half); \
232  TEST_SET_GET_VECTOR3_DOUBLE(object, variable, max - epsilon, max - epsilon, max - epsilon); \
233  TEST_SET_GET_VECTOR3_DOUBLE(object, variable, max, max, max); \
234  TEST_SET_GET_VECTOR3_DOUBLE(object, variable, max + epsilon, max + epsilon, max + epsilon); \
235  } while (false)
236 
238 #define TEST_SET_GET_STRING(object, variable) \
239  do \
240  { \
241  const char* originalStringPointer = object->Get##variable(); \
242  std::string originalString; \
243  if (originalStringPointer != nullptr) \
244  { \
245  originalString = originalStringPointer; \
246  } \
247  object->Set##variable("testing with a const char"); \
248  if (strcmp(object->Get##variable(), "testing with a const char") != 0) \
249  { \
250  std::cerr << "Error in Set/Get" #variable << " with a string literal" << std::endl; \
251  return EXIT_FAILURE; \
252  } \
253  std::string string1 = "testingIsGood"; \
254  object->Set##variable(string1.c_str()); \
255  if (object->Get##variable() != string1) \
256  { \
257  std::cerr << "Error in Set/Get" #variable << std::endl; \
258  return EXIT_FAILURE; \
259  } \
260  std::string string2 = "moreTestingIsBetter"; \
261  object->Set##variable(string2.c_str()); \
262  if (object->Get##variable() != string2) \
263  { \
264  std::cerr << "Error in Set/Get" #variable << std::endl; \
265  return EXIT_FAILURE; \
266  } \
267  if (originalStringPointer != nullptr) \
268  { \
269  object->Set##variable(originalString.c_str()); \
270  } \
271  else \
272  { \
273  object->Set##variable(nullptr); \
274  } \
275  } while (false)
276 
278 #define TEST_SET_GET_CHAR(object, variable) \
279  do \
280  { \
281  const char originalChar = object->Get##variable(); \
282  object->Set##variable('t'); \
283  if (object->Get##variable() != 't') \
284  { \
285  std::cerr << "Error in Set/Get" #variable << " with a literal 't'" << std::endl; \
286  return EXIT_FAILURE; \
287  } \
288  object->Set##variable('3'); \
289  if (object->Get##variable() != '3') \
290  { \
291  std::cerr << "Error in Set/Get" #variable << " with a literal '3'" << std::endl; \
292  return EXIT_FAILURE; \
293  } \
294  object->Set##variable(originalChar); \
295  } while (false)
296 
298 #define EXERCISE_BASIC_INTERACTOR_OBSERVER_METHODS(object) \
299  do \
300  { \
301  EXERCISE_BASIC_OBJECT_METHODS(object); \
302  vtkSmartPointer<vtkRenderer> ren1 = vtkSmartPointer<vtkRenderer>::New(); \
303  vtkSmartPointer<vtkCamera> cam1 = vtkSmartPointer<vtkCamera>::New(); \
304  ren1->SetActiveCamera(cam1); \
305  vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New(); \
306  renWin->SetMultiSamples(0); \
307  renWin->AddRenderer(ren1); \
308  if (object->GetInteractor() != nullptr) \
309  { \
310  std::cout << "Object has an interactor already defined." << std::endl; \
311  } \
312  vtkSmartPointer<vtkRenderWindowInteractor> iren = \
313  vtkSmartPointer<vtkRenderWindowInteractor>::New(); \
314  iren->SetRenderWindow(renWin); \
315  object->SetInteractor(iren); \
316  if (object->GetInteractor() != iren) \
317  { \
318  std::cerr << "Error in Set/GetInteractor" << std::endl; \
319  return EXIT_FAILURE; \
320  } \
321  if (object->GetDefaultRenderer() != nullptr) \
322  { \
323  std::cout << "Object has default renderer already defined." << std::endl; \
324  } \
325  \
326  vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New(); \
327  renWin->AddRenderer(ren); \
328  object->SetDefaultRenderer(ren); \
329  if (object->GetDefaultRenderer() != ren) \
330  { \
331  std::cerr << "Error in Set/GetDefaultRenderer, default renderer is " \
332  << (object->GetDefaultRenderer() == nullptr ? "nullptr" : "not null") \
333  << std::endl; \
334  return EXIT_FAILURE; \
335  } \
336  object->SetCurrentRenderer(ren); \
337  if (object->GetCurrentRenderer() != ren) \
338  { \
339  std::cerr << "Get current renderer failed." << std::endl; \
340  } \
341  \
342  iren->Initialize(); \
343  renWin->Render(); \
344  if (0) \
345  { \
346  object->CreateDefaultRepresentation(); \
347  TEST_SET_GET_BOOLEAN(object, Enabled); \
348  object->On(); \
349  if (!object->GetEnabled()) \
350  { \
351  std::cerr << "Error in On" << std::endl; \
352  return EXIT_FAILURE; \
353  } \
354  object->Off(); \
355  if (object->GetEnabled()) \
356  { \
357  std::cerr << "Error in Off" << std::endl; \
358  return EXIT_FAILURE; \
359  } \
360  } \
361  TEST_SET_GET_DOUBLE(object, Priority, 0.0); \
362  float min = object->GetPriorityMinValue(); \
363  float max = object->GetPriorityMaxValue(); \
364  std::cout << "Priority min = " << min << ", max = " << max << std::endl; \
365  TEST_SET_GET_DOUBLE(object, Priority, 0.1f); \
366  TEST_SET_GET_DOUBLE(object, Priority, 0.5f); \
367  TEST_SET_GET_DOUBLE(object, Priority, 0.9f); \
368  TEST_SET_GET_DOUBLE(object, Priority, 1.0f); \
369  \
370  TEST_SET_GET_BOOLEAN(object, KeyPressActivation); \
371  TEST_SET_GET_CHAR(object, KeyPressActivationValue); \
372  \
373  object->OnChar(); \
374  if (0) \
375  { \
376  double worldPt[4]; \
377  double x = 1.0, y = 1.0, z = 1.0; \
378  object->ComputeDisplayToWorld(ren, x, y, z, worldPt); \
379  std::cout << "Display " << x << "," << y << "," << z << " to world = " << worldPt[0] << "," \
380  << worldPt[1] << "," << worldPt[2] << "," << worldPt[3] << std::endl; \
381  double displayPt[3]; \
382  object->ComputeWorldToDisplay(ren, x, y, z, displayPt); \
383  std::cout << "World " << x << "," << y << "," << z << " to display = " << displayPt[0] \
384  << "," << displayPt[1] << "," << displayPt[2] << std::endl; \
385  } \
386  \
387  object->GrabFocus(nullptr, nullptr); \
388  object->ReleaseFocus(); \
389  } while (false)
390 
392 #define EXERCISE_BASIC_ABSTRACT_METHODS(object) \
393  do \
394  { \
395  EXERCISE_BASIC_INTERACTOR_OBSERVER_METHODS(object); \
396  TEST_SET_GET_BOOLEAN(object, ProcessEvents); \
397  if (object->GetEventTranslator() == nullptr) \
398  { \
399  std::cerr << "Error getting event translator, is null." << std::endl; \
400  return EXIT_FAILURE; \
401  } \
402  object->CreateDefaultRepresentation(); \
403  object->Render(); \
404  if (object->GetParent() != nullptr) \
405  { \
406  std::cerr << "Error, parent is not null." << std::endl; \
407  return EXIT_FAILURE; \
408  } \
409  } while (false)
410 
412 #define EXERCISE_BASIC_BORDER_METHODS(object) \
413  do \
414  { \
415  EXERCISE_BASIC_ABSTRACT_METHODS(object); \
416  TEST_SET_GET_BOOLEAN(object, Selectable); \
417  TEST_SET_GET_BOOLEAN(object, Resizable); \
418  } while (false)
419 
421 #define EXERCISE_BASIC_HOVER_METHODS(object) \
422  do \
423  { \
424  EXERCISE_BASIC_ABSTRACT_METHODS(object); \
425  TEST_SET_GET_INT(object, TimerDuration, 1); \
426  TEST_SET_GET_INT(object, TimerDuration, 2); \
427  TEST_SET_GET_INT(object, TimerDuration, 50000); \
428  TEST_SET_GET_INT(object, TimerDuration, 99999); \
429  TEST_SET_GET_INT(object, TimerDuration, 100000); \
430  } while (false)
431 
433 #define EXERCISE_BASIC_PROP_METHODS(className, object) \
434  do \
435  { \
436  EXERCISE_BASIC_OBJECT_METHODS(object); \
437  vtkSmartPointer<vtkPropCollection> propCollection = vtkSmartPointer<vtkPropCollection>::New(); \
438  object->GetActors(propCollection); \
439  object->GetActors2D(propCollection); \
440  object->GetVolumes(propCollection); \
441  \
442  TEST_SET_GET_BOOLEAN(object, Visibility); \
443  TEST_SET_GET_BOOLEAN(object, Pickable); \
444  TEST_SET_GET_BOOLEAN(object, Dragable); \
445  TEST_SET_GET_BOOLEAN(object, UseBounds); \
446  object->UseBoundsOff(); \
447  \
448  object->Pick(); \
449  \
450  vtkMTimeType redrawMTime = object->GetRedrawMTime(); \
451  std::cout << "Redraw Modified Time = " << redrawMTime << std::endl; \
452  \
453  vtkSmartPointer<className> copyProp = vtkSmartPointer<className>::New(); \
454  object->ShallowCopy(copyProp); \
455  \
456  object->InitPathTraversal(); \
457  \
458  vtkSmartPointer<vtkAssemblyPath> assemblyPath = vtkSmartPointer<vtkAssemblyPath>::New(); \
459  assemblyPath = object->GetNextPath(); \
460  std::cout << "Number of paths = " << object->GetNumberOfPaths() << std::endl; \
461  \
462  vtkSmartPointer<vtkMatrix4x4> mat = vtkSmartPointer<vtkMatrix4x4>::New(); \
463  object->PokeMatrix(mat); \
464  mat = object->GetMatrix(); \
465  if (mat == nullptr) \
466  { \
467  std::cout << "No matrix." << std::endl; \
468  } \
469  \
470  vtkSmartPointer<vtkInformation> info = vtkSmartPointer<vtkInformation>::New(); \
471  info = object->GetPropertyKeys(); \
472  if (info != nullptr) \
473  { \
474  info->Print(std::cout); \
475  } \
476  else \
477  { \
478  std::cout << "No property keys" << std::endl; \
479  } \
480  object->SetPropertyKeys(info); \
481  std::cout << "Has null required keys? " << object->HasKeys(nullptr) << std::endl; \
482  \
483  std::cout << "Skipping the internal render calls, requires vtkViewPort. Testing get macros." \
484  << std::endl; \
485  std::cout << "HasTranslucentPolygonalGeometry = " << object->HasTranslucentPolygonalGeometry() \
486  << std::endl; \
487  std::cout << "AllocatedRenderTime = " << object->GetAllocatedRenderTime() << std::endl; \
488  std::cout << "RenderTimeMultiplier = " << object->GetRenderTimeMultiplier() << std::endl; \
489  std::cout << "SupportsSelection = " << object->GetSupportsSelection() << std::endl; \
490  std::cout << "NumberOfConsumers = " << object->GetNumberOfConsumers() << std::endl; \
491  } while (false)
492 
493 #define NOT_DEFINED_CONSUMERS_FAIL() \
494  do \
495  { \
496  vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); \
497  object->AddConsumer(actor); \
498  if (object->IsConsumer(actor) != 1) \
499  { \
500  std::cerr << "Failed IsConsumer check for a valid consumer." << std::endl; \
501  return EXIT_FAILURE; \
502  } \
503  if (object->IsConsumer(nullptr) != 0) \
504  { \
505  std::cerr << "Failed IsConsumer check for a null consumer." << std::endl; \
506  return EXIT_FAILURE; \
507  } \
508  vtkSmartPointer<vtkActor> actor2 = object->GetConsumer(0); \
509  if (actor2 != actor) \
510  { \
511  std::cerr << "Failed get consumer check for a valid consumer." << std::endl; \
512  return EXIT_FAILURE; \
513  } \
514  object->RemoveConsumer(actor); \
515  actor2 = object->GetConsumer(0); \
516  if (actor2 != nullptr) \
517  { \
518  std::cerr << "Failed get consumer check for an invalid consumer number 0." << std::endl; \
519  return EXIT_FAILURE; \
520  } \
521  } while (false)
522 
524 // XXX(fixme): For some reason, wrapping this in a `do {} while (false)` block
525 // ends up failing the test. Opening the `do` block *after* `ren1` is declared
526 // works though. Why adding `ren1` into the scope makes the test change
527 // behavior is unknown. Leaving as a "tarbomb"-style macro for now.
528 #define EXERCISE_BASIC_REPRESENTATION_METHODS(className, object) \
529  std::cout << "Creating a renderer and a default widget..." << std::endl; \
530  vtkSmartPointer<vtkCamera> cam1 = vtkSmartPointer<vtkCamera>::New(); \
531  vtkSmartPointer<vtkRenderer> ren1 = vtkSmartPointer<vtkRenderer>::New(); \
532  ren1->SetActiveCamera(cam1); \
533  vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New(); \
534  renWin->SetMultiSamples(0); \
535  renWin->AddRenderer(ren1); \
536  vtkSmartPointer<vtkRenderWindowInteractor> iren = \
537  vtkSmartPointer<vtkRenderWindowInteractor>::New(); \
538  iren->SetRenderWindow(renWin); \
539  \
540  object->SetRenderer(ren1); \
541  vtkSmartPointer<vtkRenderer> ren2 = object->GetRenderer(); \
542  if (ren2 != ren1) \
543  { \
544  std::cerr << "Failure in GetRenderer." << std::endl; \
545  return EXIT_FAILURE; \
546  } \
547  \
548  double bounds[6] = { -1.0, 0.0, -10.0, 10.0, -5.0, 2.0 }; \
549  object->PlaceWidget(bounds); \
550  const double* bounds2 = object->GetBounds(); \
551  if (bounds2 == nullptr) \
552  { \
553  std::cout << "GetBounds is null." << std::endl; \
554  } \
555  else \
556  { \
557  std::cout << "Bounds = " << bounds[0] << "," << bounds[1] << "," << bounds[2] << "," \
558  << bounds[3] << "," << bounds[4] << "," << bounds[5] << std::endl; \
559  } \
560  \
561  double eventPos[2] = { 10.0, 10.0 }; \
562  object->StartWidgetInteraction(eventPos); \
563  object->WidgetInteraction(eventPos); \
564  object->EndWidgetInteraction(eventPos); \
565  std::cout << "InteractionState computed to be = " << object->ComputeInteractionState(10, 10, 0) \
566  << std::endl; \
567  std::cout << "GetInteractionState = " << object->GetInteractionState() << std::endl; \
568  object->Highlight(0); \
569  object->Highlight(1); \
570  \
571  TEST_SET_GET_DOUBLE_RANGE(object, PlaceFactor, 1.01, 1000.0); \
572  TEST_SET_GET_DOUBLE_RANGE(object, HandleSize, 1.002, 999.0); \
573  TEST_SET_GET_BOOLEAN(object, NeedToRender); \
574  \
575  std::cout << "Trying to get back to init state for further testing." << std::endl; \
576  object->SetPlaceFactor(0.5); \
577  object->SetHandleSize(0.05); \
578  std::cout << "Done basic rep methods" << std::endl; \
579  EXERCISE_BASIC_PROP_METHODS(className, object)
580 
582 #define EXERCISE_BASIC_ANGLE_REPRESENTATION_METHODS(className, object) \
583  do \
584  { \
585  vtkSmartPointer<vtkPointHandleRepresentation2D> phandle0 = \
586  vtkSmartPointer<vtkPointHandleRepresentation2D>::New(); \
587  object->SetHandleRepresentation(phandle0); \
588  object->InstantiateHandleRepresentation(); \
589  \
590  std::cout << "GetAngle = " << object->GetAngle() << std::endl; \
591  \
592  double pos[3]; \
593  object->GetPoint1WorldPosition(pos); \
594  std::cout << "GetPoint1WorldPosition = " << pos[0] << ", " << pos[1] << ", " << pos[2] \
595  << std::endl; \
596  object->GetCenterWorldPosition(pos); \
597  std::cout << "GetCenterWorldPosition = " << pos[0] << ", " << pos[1] << ", " << pos[2] \
598  << std::endl; \
599  object->GetPoint2WorldPosition(pos); \
600  std::cout << "GetPoint2WorldPosition = " << pos[0] << ", " << pos[1] << ", " << pos[2] \
601  << std::endl; \
602  \
603  double pos2[3]; \
604  pos2[0] = -99.0; \
605  pos2[1] = 99.0; \
606  pos2[2] = 55.0; \
607  object->SetCenterDisplayPosition(pos2); \
608  object->GetCenterDisplayPosition(pos); \
609  if (pos[0] != pos2[0] || pos[0] != pos2[0] || pos[0] != pos2[0]) \
610  { \
611  std::cerr << "Failed to SetCenterDisplayPosition to " << pos2[0] << ", " << pos2[1] << ", " \
612  << pos2[2] << ", instead got " << pos[0] << ", " << pos[1] << ", " << pos[2] \
613  << std::endl; \
614  return EXIT_FAILURE; \
615  } \
616  \
617  pos[0] = -100.0; \
618  object->SetPoint1DisplayPosition(pos2); \
619  object->GetPoint1DisplayPosition(pos); \
620  if (pos[0] != pos2[0] || pos[0] != pos2[0] || pos[0] != pos2[0]) \
621  { \
622  std::cerr << "Failed to SetPoint1DisplayPosition to " << pos2[0] << ", " << pos2[1] << ", " \
623  << pos2[2] << ", instead got " << pos[0] << ", " << pos[1] << ", " << pos[2] \
624  << std::endl; \
625  return EXIT_FAILURE; \
626  } \
627  \
628  pos[0] = 101.0; \
629  object->SetPoint2DisplayPosition(pos2); \
630  object->GetPoint2DisplayPosition(pos); \
631  if (pos[0] != pos2[0] || pos[0] != pos2[0] || pos[0] != pos2[0]) \
632  { \
633  std::cerr << "Failed to SetPoint2DisplayPosition to " << pos2[0] << ", " << pos2[1] << ", " \
634  << pos2[2] << ", instead got " << pos[0] << ", " << pos[1] << ", " << pos[2] \
635  << std::endl; \
636  return EXIT_FAILURE; \
637  } \
638  \
639  vtkSmartPointer<vtkPointHandleRepresentation2D> phandle = \
640  vtkSmartPointer<vtkPointHandleRepresentation2D>::New(); \
641  object->SetHandleRepresentation(phandle); \
642  object->InstantiateHandleRepresentation(); \
643  \
644  vtkSmartPointer<vtkHandleRepresentation> handleRep = nullptr; \
645  handleRep = object->GetPoint1Representation(); \
646  handleRep = object->GetPoint2Representation(); \
647  handleRep = object->GetCenterRepresentation(); \
648  \
649  TEST_SET_GET_INT_RANGE(object, Tolerance, 2, 99); \
650  TEST_SET_GET_STRING(object, LabelFormat); \
651  TEST_SET_GET_BOOLEAN(object, Ray1Visibility); \
652  TEST_SET_GET_BOOLEAN(object, Ray2Visibility); \
653  TEST_SET_GET_BOOLEAN(object, ArcVisibility); \
654  \
655  double e[2] = { 5.0, 1.0 }; \
656  object->CenterWidgetInteraction(e); \
657  EXERCISE_BASIC_REPRESENTATION_METHODS(className, object); \
658  } while (false)
659 
661 #define EXERCISE_BASIC_BORDER_REPRESENTATION_METHODS(className, object) \
662  do \
663  { \
664  EXERCISE_BASIC_REPRESENTATION_METHODS(className, object); \
665  \
666  double pos[2] = { 10.0, 11.0 }; \
667  double* pos2 = nullptr; \
668  object->SetPosition(pos); \
669  pos2 = object->GetPosition(); \
670  if (pos2 == nullptr) \
671  { \
672  std::cerr << "Failure in Get/Set Position pos, got null position back." << std::endl; \
673  return EXIT_FAILURE; \
674  } \
675  else if (pos2[0] != pos[0] || pos2[1] != pos[1]) \
676  { \
677  std::cerr << "Failure in Get/Set Position pos, expected " << pos[0] << ", " << pos[1] \
678  << ", instead got " << pos2[0] << ", " << pos2[1] << std::endl; \
679  return EXIT_FAILURE; \
680  } \
681  else \
682  { \
683  std::cout << "Set Position to " << pos2[0] << ", " << pos2[1] << std::endl; \
684  } \
685  \
686  pos[0] = 12.0; \
687  object->SetPosition(pos[0], pos[1]); \
688  pos2 = object->GetPosition(); \
689  if (pos2 == nullptr || pos2[0] != pos[0] || pos2[1] != pos[1]) \
690  { \
691  std::cerr << "Failure in Get/Set Position x,y, expected " << pos[0] << ", " << pos[1] \
692  << ", instead got " << pos2[0] << ", " << pos2[1] << std::endl; \
693  return EXIT_FAILURE; \
694  } \
695  vtkSmartPointer<vtkCoordinate> coord = object->GetPositionCoordinate(); \
696  pos2 = coord->GetValue(); \
697  if (pos2 == nullptr || pos2[0] != pos[0] || pos2[1] != pos[1]) \
698  { \
699  std::cerr << "Failure in Get/ Coordinate, expected " << pos[0] << ", " << pos[1] \
700  << ", instead got " << pos2[0] << ", " << pos2[1] << std::endl; \
701  return EXIT_FAILURE; \
702  } \
703  \
704  pos[0] = 44.0; \
705  object->SetPosition2(pos); \
706  pos2 = object->GetPosition2(); \
707  if (pos2 == nullptr || pos2[0] != pos[0] || pos2[1] != pos[1]) \
708  { \
709  std::cerr << "Failure in Get/Set Position2 pos, expected " << pos[0] << ", " << pos[1] \
710  << ", instead got " << pos2[0] << ", " << pos2[1] << std::endl; \
711  return EXIT_FAILURE; \
712  } \
713  pos[0] = 12.0; \
714  object->SetPosition2(pos[0], pos[1]); \
715  pos2 = object->GetPosition2(); \
716  if (pos2 == nullptr || pos2[0] != pos[0] || pos2[1] != pos[1]) \
717  { \
718  std::cerr << "Failure in Get/Set Position2 x,y, expected " << pos[0] << ", " << pos[1] \
719  << ", instead got " << pos2[0] << ", " << pos2[1] << std::endl; \
720  return EXIT_FAILURE; \
721  } \
722  coord = object->GetPosition2Coordinate(); \
723  pos2 = coord->GetValue(); \
724  if (pos2 == nullptr || pos2[0] != pos[0] || pos2[1] != pos[1]) \
725  { \
726  std::cerr << "Failure in Get/ Coordinate 2, expected " << pos[0] << ", " << pos[1] \
727  << ", instead got " << pos2[0] << ", " << pos2[1] << std::endl; \
728  return EXIT_FAILURE; \
729  } \
730  \
731  TEST_SET_GET_INT(object, ShowBorder, 0); \
732  TEST_SET_GET_INT(object, ShowBorder, 1); \
733  TEST_SET_GET_INT(object, ShowBorder, 2); \
734  object->SetShowBorderToOff(); \
735  object->SetShowBorderToOn(); \
736  object->SetShowBorderToActive(); \
737  \
738  vtkSmartPointer<vtkProperty2D> borderProperty = object->GetBorderProperty(); \
739  \
740  TEST_SET_GET_BOOLEAN(object, ProportionalResize); \
741  \
742  TEST_SET_GET_VECTOR2_INT_RANGE(object, MinimumSize, 0, 100); \
743  TEST_SET_GET_VECTOR2_INT_RANGE(object, MaximumSize, 0, 100); \
744  TEST_SET_GET_INT_RANGE(object, Tolerance, 2, 9); \
745  \
746  double* selPoint = object->GetSelectionPoint(); \
747  if (selPoint) \
748  { \
749  std::cout << "Selection Point = " << selPoint[0] << ", " << selPoint[1] << std::endl; \
750  } \
751  \
752  TEST_SET_GET_BOOLEAN(object, Moving); \
753  \
754  double size[2]; \
755  object->GetSize(size); \
756  std::cout << "Size = " << size[0] << ", " << size[1] << std::endl; \
757  \
758  int interactionState = object->ComputeInteractionState(10, 10); \
759  std::cout << "Interaction state = " << interactionState << std::endl; \
760  } while (false)
761 
763 #define TEST_SET_GET_PROPERTY(object, variable) \
764  do \
765  { \
766  vtkSmartPointer<vtkProperty> prop1 = vtkSmartPointer<vtkProperty>::New(); \
767  double colour[3] = { 0.2, 0.3, 0.4 }; \
768  prop1->SetColor(colour); \
769  node1->Set##variable(prop1); \
770  vtkSmartPointer<vtkProperty> prop = node1->Get##variable(); \
771  if (!prop) \
772  { \
773  std::cerr << "Got null variable property back after setting it!" << std::endl; \
774  return EXIT_FAILURE; \
775  } \
776  double* col = prop->GetColor(); \
777  if (!col) \
778  { \
779  std::cerr << "Got null colour back!" << std::endl; \
780  return EXIT_FAILURE; \
781  } \
782  if (col[0] != colour[0] || col[1] != colour[1] || col[2] != colour[2]) \
783  { \
784  std::cerr << "Got wrong colour back after setting it! Expected " << colour[0] << ", " \
785  << colour[1] << ", " << colour[2] << ", but got " << col[0] << ", " << col[1] \
786  << ", " << col[2] << std::endl; \
787  return EXIT_FAILURE; \
788  } \
789  } while (false)
790 
794 #define EXERCISE_BASIC_HANDLE_REPRESENTATION_METHODS(className, object) \
795  do \
796  { \
797  EXERCISE_BASIC_REPRESENTATION_METHODS(className, object); \
798  \
799  double dpos[3], wpos[3]; \
800  wpos[0] = 0.1; \
801  wpos[1] = -1.0; \
802  wpos[2] = 3.6; \
803  dpos[0] = 25; \
804  dpos[1] = 50; \
805  dpos[2] = 0.0; \
806  double pos2[3]; \
807  double* pos3; \
808  \
809  std::cout << "Testing SetWorldPosition" << std::endl; \
810  \
811  object->SetWorldPosition(wpos); \
812  std::cout << "Testing GetWorldPosition" << std::endl; \
813  object->GetWorldPosition(pos2); \
814  if (pos2[0] != wpos[0] || pos2[1] != wpos[1] || pos2[2] != wpos[2]) \
815  { \
816  std::cerr << "Failure in Get WorldPosition pos2, expected " << wpos[0] << ", " << wpos[1] \
817  << ", " << wpos[2] << ", instead got " << pos2[0] << ", " << pos2[1] << ", " \
818  << pos2[2] << std::endl; \
819  return EXIT_FAILURE; \
820  } \
821  pos3 = object->GetWorldPosition(); \
822  if (!pos3) \
823  { \
824  std::cerr << "Failure in double * GetWorldPosition , expected " << wpos[0] << ", " \
825  << wpos[1] << ", " << wpos[2] << ", instead got a null pointer." << std::endl; \
826  return EXIT_FAILURE; \
827  } \
828  if (pos3[0] != wpos[0] || pos3[1] != wpos[1] || pos3[2] != wpos[2]) \
829  { \
830  std::cerr << "Failure in double * GetWorldyPosition , expected " << wpos[0] << ", " \
831  << wpos[1] << ", " << wpos[2] << ", instead got " << pos3[0] << ", " << pos3[1] \
832  << ", " << pos3[2] << std::endl; \
833  return EXIT_FAILURE; \
834  } \
835  std::cout << "Done testing world position." << std::endl; \
836  \
837  std::cout << "Testing Set/Get Display Position" << std::endl; \
838  \
839  object->GetDisplayPosition(pos2); \
840  std::cout << "After GetDisplayPosition." << std::endl; \
841  object->SetDisplayPosition(dpos); \
842  std::cout << "After SetDisplayPosition" << std::endl; \
843  object->GetDisplayPosition(pos2); \
844  std::cout << "After GetDisplayPosition second time." << std::endl; \
845  if (pos2[0] != 0 || pos2[1] != 0) \
846  { \
847  std::cerr << "Failure in GetDisplayPosition pos2, expected (0,0) instead got " << pos2[0] \
848  << ", " << pos2[1] << std::endl; \
849  return EXIT_FAILURE; \
850  } \
851  pos3 = object->GetDisplayPosition(); \
852  if (!pos3) \
853  { \
854  std::cerr \
855  << "Failure in double * GetDisplayPosition, expected (0,0) instead got a null pointer." \
856  << std::endl; \
857  return EXIT_FAILURE; \
858  } \
859  if (pos3[0] != 0 || pos3[1] != 0) \
860  { \
861  std::cerr << "Failure in double * GetDisplayPosition , expected (0,0) instead got " \
862  << pos3[0] << ", " << pos3[1] << std::endl; \
863  return EXIT_FAILURE; \
864  } \
865  TEST_SET_GET_INT_RANGE(object, Tolerance, 2, 99); \
866  TEST_SET_GET_BOOLEAN(object, ActiveRepresentation); \
867  TEST_SET_GET_BOOLEAN(object, Constrained); \
868  \
869  vtkSmartPointer<vtkRenderer> ren3 = object->GetRenderer(); \
870  double posToCheck[3] = { 0.0, 0.0, 0.0 }; \
871  int flag = object->CheckConstraint(ren3, posToCheck); \
872  std::cout << "Check Constraint = " << flag << std::endl; \
873  \
874  std::cout << "MTime = " << object->GetMTime() << std::endl; \
875  \
876  vtkSmartPointer<vtkPointPlacer> pplacer = vtkSmartPointer<vtkPointPlacer>::New(); \
877  object->SetPointPlacer(pplacer); \
878  vtkSmartPointer<vtkPointPlacer> pplacer2 = object->GetPointPlacer(); \
879  if (pplacer2 != pplacer) \
880  { \
881  std::cerr << "Error in Set/Get point placer." << std::endl; \
882  return EXIT_FAILURE; \
883  } \
884  flag = object->CheckConstraint(ren3, posToCheck); \
885  std::cout << "Check Constraint after setting point placer = " << flag << std::endl; \
886  } while (false)
887 
889 #define EXERCISE_BASIC_ABSTRACT_POLYGONAL_HANDLE_REPRESENTATION3D_METHODS(className, object) \
890  do \
891  { \
892  EXERCISE_BASIC_HANDLE_REPRESENTATION_METHODS(className, object); \
893  \
894  vtkSmartPointer<vtkPolyData> pd = vtkSmartPointer<vtkPolyData>::New(); \
895  object->SetHandle(pd); \
896  vtkSmartPointer<vtkPolyData> pd2 = object->GetHandle(); \
897  if (pd2 == nullptr) \
898  { \
899  std::cerr << "Error getting handle, null pointer." << std::endl; \
900  return EXIT_FAILURE; \
901  } \
902  if (pd2 != pd) \
903  { \
904  std::cerr << "Error getting handle, not the same as set." << std::endl; \
905  return EXIT_FAILURE; \
906  } \
907  TEST_SET_GET_PROPERTY(object, Property); \
908  TEST_SET_GET_PROPERTY(object, SelectedProperty); \
909  \
910  vtkSmartPointer<vtkAbstractTransform> at = object->GetTransform(); \
911  \
912  TEST_SET_GET_BOOLEAN(object, LabelVisibility); \
913  TEST_SET_GET_STRING(object, LabelText); \
914  TEST_SET_GET_VECTOR3_DOUBLE_RANGE(object, LabelTextScale, 0.0, 10.0); \
915  \
916  vtkSmartPointer<vtkFollower> follower = object->GetLabelTextActor(); \
917  if (follower == nullptr) \
918  { \
919  std::cout << "Follower is null." << std::endl; \
920  } \
921  \
922  object->SetUniformScale(-1.0); \
923  object->SetUniformScale(0.0); \
924  object->SetUniformScale(1.0); \
925  object->SetUniformScale(35.44); \
926  \
927  TEST_SET_GET_BOOLEAN(object, HandleVisibility); \
928  } while (false)
929 #endif