/*========================================================================= Program: Visualization Toolkit Module: TestImplicitCylinderWidget.cxx Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "vtkSmartPointer.h" #include "vtkActor.h" #include "vtkAppendPolyData.h" #include "vtkClipPolyData.h" #include "vtkCommand.h" #include "vtkConeSource.h" #include "vtkCylinder.h" #include "vtkGlyph3D.h" #include "vtkImplicitCylinderRepresentation.h" #include "vtkImplicitCylinderWidget.h" #include "vtkInteractorEventRecorder.h" #include "vtkLODActor.h" #include "vtkPolyData.h" #include "vtkPolyDataMapper.h" #include "vtkProperty.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "vtkRenderer.h" #include "vtkSphereSource.h" namespace { const char eventLog[] = "# StreamVersion 1\n" "CharEvent 108 202 0 0 105 1 i\n" "MouseWheelBackwardEvent 161 106 0 0 0 0 i\n" "MouseWheelBackwardEvent 161 106 0 0 0 1 i\n" "MouseWheelBackwardEvent 161 106 0 0 0 0 i\n" "MouseWheelBackwardEvent 161 106 0 0 0 1 i\n" "MouseWheelBackwardEvent 161 106 0 0 0 0 i\n" "MouseWheelBackwardEvent 161 106 0 0 0 1 i\n" "MouseWheelBackwardEvent 161 106 0 0 0 0 i\n" "MouseWheelBackwardEvent 161 106 0 0 0 1 i\n" "LeftButtonPressEvent 174 264 0 0 0 0 i\n" "MouseMoveEvent 177 265 0 0 0 0 i\n" "MouseMoveEvent 194 266 0 0 0 0 i\n" "MouseMoveEvent 261 266 0 0 0 0 i\n" "MouseMoveEvent 313 268 0 0 0 0 i\n" "MouseMoveEvent 359 268 0 0 0 0 i\n" "MouseMoveEvent 395 266 0 0 0 0 i\n" "MouseMoveEvent 437 266 0 0 0 0 i\n" "MouseMoveEvent 475 262 0 0 0 0 i\n" "MouseMoveEvent 515 262 0 0 0 0 i\n" "MouseMoveEvent 549 259 0 0 0 0 i\n" "MouseMoveEvent 579 259 0 0 0 0 i\n" "MouseMoveEvent 599 259 0 0 0 0 i\n" "MouseMoveEvent 605 259 0 0 0 0 i\n" "MouseMoveEvent 611 259 0 0 0 0 i\n" "MouseMoveEvent 618 259 0 0 0 0 i\n" "MouseMoveEvent 622 255 0 0 0 0 i\n" "MouseMoveEvent 626 245 0 0 0 0 i\n" "MouseMoveEvent 632 227 0 0 0 0 i\n" "MouseMoveEvent 639 207 0 0 0 0 i\n" "MouseMoveEvent 646 190 0 0 0 0 i\n" "MouseMoveEvent 649 177 0 0 0 0 i\n" "MouseMoveEvent 652 168 0 0 0 0 i\n" "MouseMoveEvent 656 155 0 0 0 0 i\n" "MouseMoveEvent 658 144 0 0 0 0 i\n" "MouseMoveEvent 662 133 0 0 0 0 i\n" "MouseMoveEvent 664 118 0 0 0 0 i\n" "MouseMoveEvent 666 107 0 0 0 0 i\n" "MouseMoveEvent 668 97 0 0 0 0 i\n" "MouseMoveEvent 670 84 0 0 0 0 i\n" "MouseMoveEvent 671 73 0 0 0 0 i\n" "MouseMoveEvent 675 62 0 0 0 0 i\n" "MouseMoveEvent 677 53 0 0 0 0 i\n" "MouseMoveEvent 681 40 0 0 0 0 i\n" "MouseMoveEvent 686 12 0 0 0 0 i\n" "MouseMoveEvent 688 6 0 0 0 0 i\n" "MouseMoveEvent 689 -4 0 0 0 0 i\n" "MouseMoveEvent 690 -20 0 0 0 0 i\n" "MouseMoveEvent 692 -29 0 0 0 0 i\n" "MouseMoveEvent 688 -35 0 0 0 0 i\n" "MouseMoveEvent 661 -42 0 0 0 0 i\n" "MouseMoveEvent 617 -47 0 0 0 0 i\n" "MouseMoveEvent 577 -50 0 0 0 0 i\n" "MouseMoveEvent 554 -55 0 0 0 0 i\n" "MouseMoveEvent 523 -58 0 0 0 0 i\n" "MouseMoveEvent 497 -62 0 0 0 0 i\n" "MouseMoveEvent 468 -64 0 0 0 0 i\n" "MouseMoveEvent 438 -66 0 0 0 0 i\n" "MouseMoveEvent 412 -70 0 0 0 0 i\n" "MouseMoveEvent 388 -73 0 0 0 0 i\n" "MouseMoveEvent 350 -78 0 0 0 0 i\n" "MouseMoveEvent 317 -80 0 0 0 0 i\n" "MouseMoveEvent 270 -86 0 0 0 0 i\n" "MouseMoveEvent 223 -90 0 0 0 0 i\n" "MouseMoveEvent 182 -95 0 0 0 0 i\n" "MouseMoveEvent 149 -99 0 0 0 0 i\n" "MouseMoveEvent 109 -101 0 0 0 0 i\n" "MouseMoveEvent 75 -103 0 0 0 0 i\n" "MouseMoveEvent 39 -103 0 0 0 0 i\n" "MouseMoveEvent 1 -103 0 0 0 0 i\n" "MouseMoveEvent -8 -103 0 0 0 0 i\n" "MouseMoveEvent -13 -102 0 0 0 0 i\n" "MouseMoveEvent -20 -92 0 0 0 0 i\n" "MouseMoveEvent -34 -75 0 0 0 0 i\n" "MouseMoveEvent -43 -58 0 0 0 0 i\n" "MouseMoveEvent -59 -36 0 0 0 0 i\n" "MouseMoveEvent -69 -6 0 0 0 0 i\n" "MouseMoveEvent -81 20 0 0 0 0 i\n" "MouseMoveEvent -96 59 0 0 0 0 i\n" "MouseMoveEvent -104 89 0 0 0 0 i\n" "MouseMoveEvent -115 121 0 0 0 0 i\n" "MouseMoveEvent -129 154 0 0 0 0 i\n" "MouseMoveEvent -137 181 0 0 0 0 i\n" "MouseMoveEvent -145 209 0 0 0 0 i\n" "MouseMoveEvent -152 234 0 0 0 0 i\n" "MouseMoveEvent -155 253 0 0 0 0 i\n" "MouseMoveEvent -160 275 0 0 0 0 i\n" "MouseMoveEvent -162 298 0 0 0 0 i\n" "MouseMoveEvent -167 330 0 0 0 0 i\n" "MouseMoveEvent -169 346 0 0 0 0 i\n" "MouseMoveEvent -170 366 0 0 0 0 i\n" "MouseMoveEvent -174 387 0 0 0 0 i\n" "MouseMoveEvent -176 413 0 0 0 0 i\n" "MouseMoveEvent -177 439 0 0 0 0 i\n" "MouseMoveEvent -177 467 0 0 0 0 i\n" "MouseMoveEvent -177 492 0 0 0 0 i\n" "MouseMoveEvent -177 513 0 0 0 0 i\n" "MouseMoveEvent -177 520 0 0 0 0 i\n" "MouseMoveEvent -176 525 0 0 0 0 i\n" "MouseMoveEvent -161 529 0 0 0 0 i\n" "MouseMoveEvent -129 535 0 0 0 0 i\n" "MouseMoveEvent -90 535 0 0 0 0 i\n" "MouseMoveEvent -49 541 0 0 0 0 i\n" "MouseMoveEvent -2 541 0 0 0 0 i\n" "MouseMoveEvent 42 541 0 0 0 0 i\n" "MouseMoveEvent 85 544 0 0 0 0 i\n" "MouseMoveEvent 115 547 0 0 0 0 i\n" "MouseMoveEvent 145 547 0 0 0 0 i\n" "MouseMoveEvent 186 547 0 0 0 0 i\n" "MouseMoveEvent 234 547 0 0 0 0 i\n" "MouseMoveEvent 272 547 0 0 0 0 i\n" "MouseMoveEvent 299 547 0 0 0 0 i\n" "MouseMoveEvent 320 549 0 0 0 0 i\n" "MouseMoveEvent 345 549 0 0 0 0 i\n" "MouseMoveEvent 365 549 0 0 0 0 i\n" "MouseMoveEvent 382 549 0 0 0 0 i\n" "MouseMoveEvent 410 549 0 0 0 0 i\n" "MouseMoveEvent 439 549 0 0 0 0 i\n" "MouseMoveEvent 465 547 0 0 0 0 i\n" "MouseMoveEvent 482 545 0 0 0 0 i\n" "MouseMoveEvent 484 538 0 0 0 0 i\n" "MouseMoveEvent 484 529 0 0 0 0 i\n" "MouseMoveEvent 491 507 0 0 0 0 i\n" "MouseMoveEvent 492 498 0 0 0 0 i\n" "MouseMoveEvent 494 488 0 0 0 0 i\n" "MouseMoveEvent 496 480 0 0 0 0 i\n" "MouseMoveEvent 496 476 0 0 0 0 i\n" "MouseMoveEvent 497 468 0 0 0 0 i\n" "MouseMoveEvent 499 459 0 0 0 0 i\n" "MouseMoveEvent 500 450 0 0 0 0 i\n" "MouseMoveEvent 501 441 0 0 0 0 i\n" "MouseMoveEvent 502 433 0 0 0 0 i\n" "MouseMoveEvent 504 428 0 0 0 0 i\n" "MouseMoveEvent 505 420 0 0 0 0 i\n" "MouseMoveEvent 505 415 0 0 0 0 i\n" "MouseMoveEvent 506 409 0 0 0 0 i\n" "MouseMoveEvent 506 403 0 0 0 0 i\n" "MouseMoveEvent 506 395 0 0 0 0 i\n" "MouseMoveEvent 507 389 0 0 0 0 i\n" "MouseMoveEvent 507 383 0 0 0 0 i\n" "MouseMoveEvent 507 376 0 0 0 0 i\n" "MouseMoveEvent 507 368 0 0 0 0 i\n" "MouseMoveEvent 508 358 0 0 0 0 i\n" "MouseMoveEvent 509 350 0 0 0 0 i\n" "MouseMoveEvent 509 346 0 0 0 0 i\n" "MouseMoveEvent 509 341 0 0 0 0 i\n" "MouseMoveEvent 510 335 0 0 0 0 i\n" "MouseMoveEvent 510 333 0 0 0 0 i\n" "MouseMoveEvent 510 330 0 0 0 0 i\n" "MouseMoveEvent 510 325 0 0 0 0 i\n" "MouseMoveEvent 510 321 0 0 0 0 i\n" "MouseMoveEvent 510 318 0 0 0 0 i\n" "MouseMoveEvent 511 310 0 0 0 0 i\n" "MouseMoveEvent 512 304 0 0 0 0 i\n" "MouseMoveEvent 512 298 0 0 0 0 i\n" "MouseMoveEvent 514 290 0 0 0 0 i\n" "MouseMoveEvent 515 284 0 0 0 0 i\n" "MouseMoveEvent 515 278 0 0 0 0 i\n" "MouseMoveEvent 515 270 0 0 0 0 i\n" "MouseMoveEvent 516 260 0 0 0 0 i\n" "MouseMoveEvent 516 253 0 0 0 0 i\n" "MouseMoveEvent 517 242 0 0 0 0 i\n" "MouseMoveEvent 517 238 0 0 0 0 i\n" "MouseMoveEvent 519 234 0 0 0 0 i\n" "MouseMoveEvent 519 231 0 0 0 0 i\n" "MouseMoveEvent 519 229 0 0 0 0 i\n" "MouseMoveEvent 519 225 0 0 0 0 i\n" "MouseMoveEvent 519 221 0 0 0 0 i\n" "MouseMoveEvent 519 218 0 0 0 0 i\n" "MouseMoveEvent 520 211 0 0 0 0 i\n" "MouseMoveEvent 520 207 0 0 0 0 i\n" "MouseMoveEvent 521 203 0 0 0 0 i\n" "MouseMoveEvent 521 199 0 0 0 0 i\n" "MouseMoveEvent 520 197 0 0 0 0 i\n" "MouseMoveEvent 518 197 0 0 0 0 i\n" "MouseMoveEvent 515 197 0 0 0 0 i\n" "MouseMoveEvent 513 197 0 0 0 0 i\n" "MouseMoveEvent 504 197 0 0 0 0 i\n" "MouseMoveEvent 494 197 0 0 0 0 i\n" "MouseMoveEvent 485 197 0 0 0 0 i\n" "MouseMoveEvent 480 197 0 0 0 0 i\n" "MouseMoveEvent 472 197 0 0 0 0 i\n" "MouseMoveEvent 462 197 0 0 0 0 i\n" "MouseMoveEvent 455 197 0 0 0 0 i\n" "MouseMoveEvent 450 197 0 0 0 0 i\n" "MouseMoveEvent 444 197 0 0 0 0 i\n" "MouseMoveEvent 439 197 0 0 0 0 i\n" "MouseMoveEvent 433 197 0 0 0 0 i\n" "MouseMoveEvent 427 197 0 0 0 0 i\n" "MouseMoveEvent 419 197 0 0 0 0 i\n" "MouseMoveEvent 412 197 0 0 0 0 i\n" "MouseMoveEvent 405 197 0 0 0 0 i\n" "MouseMoveEvent 399 197 0 0 0 0 i\n" "MouseMoveEvent 393 197 0 0 0 0 i\n" "MouseMoveEvent 385 197 0 0 0 0 i\n" "MouseMoveEvent 377 197 0 0 0 0 i\n" "MouseMoveEvent 368 197 0 0 0 0 i\n" "MouseMoveEvent 362 197 0 0 0 0 i\n" "MouseMoveEvent 355 197 0 0 0 0 i\n" "MouseMoveEvent 347 197 0 0 0 0 i\n" "MouseMoveEvent 338 197 0 0 0 0 i\n" "MouseMoveEvent 329 197 0 0 0 0 i\n" "MouseMoveEvent 324 197 0 0 0 0 i\n" "MouseMoveEvent 319 197 0 0 0 0 i\n" "MouseMoveEvent 313 197 0 0 0 0 i\n" "MouseMoveEvent 308 197 0 0 0 0 i\n" "MouseMoveEvent 304 197 0 0 0 0 i\n" "MouseMoveEvent 300 197 0 0 0 0 i\n" "MouseMoveEvent 297 198 0 0 0 0 i\n" "MouseMoveEvent 297 202 0 0 0 0 i\n" "MouseMoveEvent 297 206 0 0 0 0 i\n" "MouseMoveEvent 297 211 0 0 0 0 i\n" "MouseMoveEvent 299 215 0 0 0 0 i\n" "MouseMoveEvent 299 220 0 0 0 0 i\n" "MouseMoveEvent 300 222 0 0 0 0 i\n" "MouseMoveEvent 300 225 0 0 0 0 i\n" "MouseMoveEvent 300 227 0 0 0 0 i\n" "MouseMoveEvent 300 234 0 0 0 0 i\n" "MouseMoveEvent 300 236 0 0 0 0 i\n" "MouseMoveEvent 300 239 0 0 0 0 i\n" "MouseMoveEvent 300 241 0 0 0 0 i\n" "MouseMoveEvent 300 244 0 0 0 0 i\n" "MouseMoveEvent 300 246 0 0 0 0 i\n" "MouseMoveEvent 299 249 0 0 0 0 i\n" "MouseMoveEvent 299 251 0 0 0 0 i\n" "MouseMoveEvent 299 254 0 0 0 0 i\n" "MouseMoveEvent 299 257 0 0 0 0 i\n" "MouseMoveEvent 299 260 0 0 0 0 i\n" "MouseMoveEvent 299 265 0 0 0 0 i\n" "MouseMoveEvent 299 267 0 0 0 0 i\n" "MouseMoveEvent 299 270 0 0 0 0 i\n" "MouseMoveEvent 299 272 0 0 0 0 i\n" "MouseMoveEvent 299 275 0 0 0 0 i\n" "MouseMoveEvent 298 275 0 0 0 0 i\n" "LeftButtonReleaseEvent 298 275 0 0 0 0 i\n"; // This does the actual work: updates the vtkCylinder implicit function. // This in turn causes the pipeline to update and clip the object. // Callback for the interaction class vtkTICWCallback : public vtkCommand { public: static vtkTICWCallback* New() { return new vtkTICWCallback; } void Execute(vtkObject* caller, unsigned long, void*) override { vtkImplicitCylinderWidget* cylWidget = reinterpret_cast(caller); vtkImplicitCylinderRepresentation* rep = reinterpret_cast(cylWidget->GetRepresentation()); rep->GetCylinder(this->Cylinder); this->Actor->VisibilityOn(); } vtkTICWCallback() : Cylinder(nullptr) , Actor(nullptr) { } vtkCylinder* Cylinder; vtkActor* Actor; }; } // anonymous namespace int TestImplicitCylinderWidget2(int vtkNotUsed(argc), char* vtkNotUsed(argv)[]) { // Create a mace out of filters. vtkSmartPointer sphere = vtkSmartPointer::New(); vtkSmartPointer cone = vtkSmartPointer::New(); vtkSmartPointer glyph = vtkSmartPointer::New(); glyph->SetInputConnection(sphere->GetOutputPort()); glyph->SetSourceConnection(cone->GetOutputPort()); glyph->SetVectorModeToUseNormal(); glyph->SetScaleModeToScaleByVector(); glyph->SetScaleFactor(0.25); glyph->Update(); // The sphere and spikes are appended into a single polydata. // This just makes things simpler to manage. vtkSmartPointer apd = vtkSmartPointer::New(); apd->AddInputConnection(glyph->GetOutputPort()); apd->AddInputConnection(sphere->GetOutputPort()); vtkSmartPointer maceMapper = vtkSmartPointer::New(); maceMapper->SetInputConnection(apd->GetOutputPort()); vtkSmartPointer maceActor = vtkSmartPointer::New(); maceActor->SetMapper(maceMapper); maceActor->VisibilityOn(); // This portion of the code clips the mace with the vtkCylinders // implicit function. The clipped region is colored green. vtkSmartPointer cylinder = vtkSmartPointer::New(); vtkSmartPointer clipper = vtkSmartPointer::New(); clipper->SetInputConnection(apd->GetOutputPort()); clipper->SetClipFunction(cylinder); clipper->InsideOutOn(); vtkSmartPointer selectMapper = vtkSmartPointer::New(); selectMapper->SetInputConnection(clipper->GetOutputPort()); vtkSmartPointer selectActor = vtkSmartPointer::New(); selectActor->SetMapper(selectMapper); selectActor->GetProperty()->SetColor(0, 1, 0); selectActor->VisibilityOff(); selectActor->SetScale(1.01, 1.01, 1.01); // Create the RenderWindow, Renderer and both Actors vtkSmartPointer ren1 = vtkSmartPointer::New(); vtkSmartPointer renWin = vtkSmartPointer::New(); renWin->AddRenderer(ren1); vtkSmartPointer iren = vtkSmartPointer::New(); iren->SetRenderWindow(renWin); // The SetInteractor method is how 3D widgets are associated with the render // window interactor. Internally, SetInteractor sets up a bunch of callbacks // using the Command/Observer mechanism (AddObserver()). vtkSmartPointer myCallback = vtkSmartPointer::New(); myCallback->Cylinder = cylinder; myCallback->Actor = selectActor; vtkSmartPointer rep = vtkSmartPointer::New(); rep->SetPlaceFactor(1.25); rep->PlaceWidget(glyph->GetOutput()->GetBounds()); vtkSmartPointer cylWidget = vtkSmartPointer::New(); cylWidget->SetInteractor(iren); cylWidget->SetRepresentation(rep); cylWidget->AddObserver(vtkCommand::InteractionEvent, myCallback); ren1->AddActor(maceActor); ren1->AddActor(selectActor); // Add the actors to the renderer, set the background and size ren1->SetBackground(0.1, 0.2, 0.4); renWin->SetSize(300, 300); renWin->SetMultiSamples(0); // Tests double wbounds[6]; double center[3], center1[3], center2[3]; cylWidget->SetEnabled(1); rep->GetCenter(center); // #1: With ConstrainCenter on, center SHOULD NOT be settable outside widget bounds rep->ConstrainToWidgetBoundsOn(); rep->GetWidgetBounds(wbounds); rep->SetCenter(wbounds[1] + 1.0, wbounds[3] + 1.0, wbounds[5] + 1.0); rep->GetCenter(center1); if (center1[0] > wbounds[1] || center1[1] > wbounds[3] || center1[2] > wbounds[5]) { std::cerr << "center (" << center1[0] << "," << center1[1] << "," << center1[2] << ") outside widget bounds (" << wbounds[0] << "-" << wbounds[1] << "," << wbounds[2] << "-" << wbounds[3] << "," << wbounds[4] << "-" << wbounds[5] << std::endl; return EXIT_FAILURE; } // #2: With ConstrainCenter off, center SHOULD be settable outside current widget bounds. rep->ConstrainToWidgetBoundsOff(); center1[0] = wbounds[1] + 1.0; center1[1] = wbounds[3] + 1.0; center1[2] = wbounds[5] + 1.0; rep->SetCenter(center1); rep->GetCenter(center2); if (center1[0] != center2[0] || center1[1] != center2[1] || center1[2] != center2[2]) { std::cerr << "center not set correctly. expected (" << center1[0] << "," << center1[1] << "," << center1[2] << "), got: (" << center2[0] << "," << center2[1] << "," << center2[2] << ")" << std::endl; return EXIT_FAILURE; } rep->SetCenter(center); cylWidget->SetEnabled(0); // #3: With ConstrainCenter on and OutsideBounds off, the translation of the // widget should be limited rep->OutsideBoundsOff(); rep->ConstrainToWidgetBoundsOn(); vtkSmartPointer recorder = vtkSmartPointer::New(); recorder->SetInteractor(iren); #if 0 // uncomment if recording recorder->SetFileName("record.log"); recorder->Record(); iren->Initialize(); renWin->Render(); iren->Start(); recorder->Off(); #else recorder->ReadFromInputStringOn(); recorder->SetInputString(eventLog); // render the image iren->Initialize(); renWin->Render(); recorder->Play(); // Remove the observers so we can go interactive. Without this the "-I" // testing option fails. recorder->Off(); iren->Start(); #endif return EXIT_SUCCESS; }