VTK  9.3.20240420
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"
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