/*========================================================================= Program: Visualization Toolkit Module: vtkPlaneWidget.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 "vtkPlaneWidget.h" #include "vtkActor.h" #include "vtkAssemblyNode.h" #include "vtkAssemblyPath.h" #include "vtkCallbackCommand.h" #include "vtkCamera.h" #include "vtkCellArray.h" #include "vtkCellPicker.h" #include "vtkConeSource.h" #include "vtkDoubleArray.h" #include "vtkFloatArray.h" #include "vtkLineSource.h" #include "vtkMath.h" #include "vtkObjectFactory.h" #include "vtkPickingManager.h" #include "vtkPlane.h" #include "vtkPlaneSource.h" #include "vtkPlanes.h" #include "vtkPolyData.h" #include "vtkPolyDataMapper.h" #include "vtkProperty.h" #include "vtkRenderWindowInteractor.h" #include "vtkRenderer.h" #include "vtkSphereSource.h" #include "vtkTransform.h" vtkStandardNewMacro(vtkPlaneWidget); vtkCxxSetObjectMacro(vtkPlaneWidget, PlaneProperty, vtkProperty); vtkPlaneWidget::vtkPlaneWidget() { this->State = vtkPlaneWidget::Start; this->EventCallbackCommand->SetCallback(vtkPlaneWidget::ProcessEvents); this->NormalToXAxis = 0; this->NormalToYAxis = 0; this->NormalToZAxis = 0; this->Representation = VTK_PLANE_WIREFRAME; // Build the representation of the widget int i; // Represent the plane this->PlaneSource = vtkPlaneSource::New(); this->PlaneSource->SetXResolution(4); this->PlaneSource->SetYResolution(4); this->PlaneOutline = vtkPolyData::New(); vtkPoints* pts = vtkPoints::New(); pts->SetNumberOfPoints(4); vtkCellArray* outline = vtkCellArray::New(); outline->InsertNextCell(4); outline->InsertCellPoint(0); outline->InsertCellPoint(1); outline->InsertCellPoint(2); outline->InsertCellPoint(3); this->PlaneOutline->SetPoints(pts); pts->Delete(); this->PlaneOutline->SetPolys(outline); outline->Delete(); this->PlaneMapper = vtkPolyDataMapper::New(); this->PlaneMapper->SetInputConnection(this->PlaneSource->GetOutputPort()); this->PlaneActor = vtkActor::New(); this->PlaneActor->SetMapper(this->PlaneMapper); // Create the handles this->Handle = new vtkActor*[4]; this->HandleMapper = new vtkPolyDataMapper*[4]; this->HandleGeometry = new vtkSphereSource*[4]; for (i = 0; i < 4; i++) { this->HandleGeometry[i] = vtkSphereSource::New(); this->HandleGeometry[i]->SetThetaResolution(16); this->HandleGeometry[i]->SetPhiResolution(8); this->HandleMapper[i] = vtkPolyDataMapper::New(); this->HandleMapper[i]->SetInputConnection(this->HandleGeometry[i]->GetOutputPort()); this->Handle[i] = vtkActor::New(); this->Handle[i]->SetMapper(this->HandleMapper[i]); } // Create the + plane normal this->LineSource = vtkLineSource::New(); this->LineSource->SetResolution(1); this->LineMapper = vtkPolyDataMapper::New(); this->LineMapper->SetInputConnection(this->LineSource->GetOutputPort()); this->LineActor = vtkActor::New(); this->LineActor->SetMapper(this->LineMapper); this->ConeSource = vtkConeSource::New(); this->ConeSource->SetResolution(12); this->ConeSource->SetAngle(25.0); this->ConeMapper = vtkPolyDataMapper::New(); this->ConeMapper->SetInputConnection(this->ConeSource->GetOutputPort()); this->ConeActor = vtkActor::New(); this->ConeActor->SetMapper(this->ConeMapper); // Create the - plane normal this->LineSource2 = vtkLineSource::New(); this->LineSource2->SetResolution(1); this->LineMapper2 = vtkPolyDataMapper::New(); this->LineMapper2->SetInputConnection(this->LineSource2->GetOutputPort()); this->LineActor2 = vtkActor::New(); this->LineActor2->SetMapper(this->LineMapper2); this->ConeSource2 = vtkConeSource::New(); this->ConeSource2->SetResolution(12); this->ConeSource2->SetAngle(25.0); this->ConeMapper2 = vtkPolyDataMapper::New(); this->ConeMapper2->SetInputConnection(this->ConeSource2->GetOutputPort()); this->ConeActor2 = vtkActor::New(); this->ConeActor2->SetMapper(this->ConeMapper2); this->Transform = vtkTransform::New(); // Define the point coordinates double bounds[6]; bounds[0] = -0.5; bounds[1] = 0.5; bounds[2] = -0.5; bounds[3] = 0.5; bounds[4] = -0.5; bounds[5] = 0.5; // Manage the picking stuff this->HandlePicker = vtkCellPicker::New(); this->HandlePicker->SetTolerance(0.001); for (i = 0; i < 4; i++) { this->HandlePicker->AddPickList(this->Handle[i]); } this->HandlePicker->PickFromListOn(); this->PlanePicker = vtkCellPicker::New(); this->PlanePicker->SetTolerance(0.005); // need some fluff this->PlanePicker->AddPickList(this->PlaneActor); this->PlanePicker->AddPickList(this->ConeActor); this->PlanePicker->AddPickList(this->LineActor); this->PlanePicker->AddPickList(this->ConeActor2); this->PlanePicker->AddPickList(this->LineActor2); this->PlanePicker->PickFromListOn(); this->CurrentHandle = nullptr; this->LastPickValid = 0; this->HandleSizeFactor = 1.25; this->SetHandleSize(0.05); // Set up the initial properties this->CreateDefaultProperties(); this->SelectRepresentation(); // Initial creation of the widget, serves to initialize it // Call PlaceWidget() LAST in the constructor as it depends on ivar // values. this->PlaceWidget(bounds); } vtkPlaneWidget::~vtkPlaneWidget() { this->PlaneActor->Delete(); this->PlaneMapper->Delete(); this->PlaneSource->Delete(); this->PlaneOutline->Delete(); for (int i = 0; i < 4; i++) { this->HandleGeometry[i]->Delete(); this->HandleMapper[i]->Delete(); this->Handle[i]->Delete(); } delete[] this->Handle; delete[] this->HandleMapper; delete[] this->HandleGeometry; this->ConeActor->Delete(); this->ConeMapper->Delete(); this->ConeSource->Delete(); this->LineActor->Delete(); this->LineMapper->Delete(); this->LineSource->Delete(); this->ConeActor2->Delete(); this->ConeMapper2->Delete(); this->ConeSource2->Delete(); this->LineActor2->Delete(); this->LineMapper2->Delete(); this->LineSource2->Delete(); this->HandlePicker->Delete(); this->PlanePicker->Delete(); if (this->HandleProperty) { this->HandleProperty->Delete(); this->HandleProperty = nullptr; } if (this->SelectedHandleProperty) { this->SelectedHandleProperty->Delete(); this->SelectedHandleProperty = nullptr; } if (this->PlaneProperty) { this->PlaneProperty->Delete(); this->PlaneProperty = nullptr; } if (this->SelectedPlaneProperty) { this->SelectedPlaneProperty->Delete(); this->SelectedPlaneProperty = nullptr; } this->Transform->Delete(); } void vtkPlaneWidget::SetEnabled(int enabling) { if (!this->Interactor) { vtkErrorMacro(<< "The interactor must be set prior to enabling/disabling widget"); return; } if (enabling) //----------------------------------------------------------- { vtkDebugMacro(<< "Enabling plane widget"); if (this->Enabled) // already enabled, just return { return; } if (!this->CurrentRenderer) { this->SetCurrentRenderer(this->Interactor->FindPokedRenderer( this->Interactor->GetLastEventPosition()[0], this->Interactor->GetLastEventPosition()[1])); if (this->CurrentRenderer == nullptr) { return; } } this->Enabled = 1; // listen for the following events vtkRenderWindowInteractor* i = this->Interactor; i->AddObserver(vtkCommand::MouseMoveEvent, this->EventCallbackCommand, this->Priority); i->AddObserver(vtkCommand::LeftButtonPressEvent, this->EventCallbackCommand, this->Priority); i->AddObserver(vtkCommand::LeftButtonReleaseEvent, this->EventCallbackCommand, this->Priority); i->AddObserver(vtkCommand::MiddleButtonPressEvent, this->EventCallbackCommand, this->Priority); i->AddObserver( vtkCommand::MiddleButtonReleaseEvent, this->EventCallbackCommand, this->Priority); i->AddObserver(vtkCommand::RightButtonPressEvent, this->EventCallbackCommand, this->Priority); i->AddObserver(vtkCommand::RightButtonReleaseEvent, this->EventCallbackCommand, this->Priority); i->AddObserver(vtkCommand::StartPinchEvent, this->EventCallbackCommand, this->Priority); i->AddObserver(vtkCommand::PinchEvent, this->EventCallbackCommand, this->Priority); i->AddObserver(vtkCommand::EndPinchEvent, this->EventCallbackCommand, this->Priority); // Add the plane this->CurrentRenderer->AddActor(this->PlaneActor); this->PlaneActor->SetProperty(this->PlaneProperty); // turn on the handles for (int j = 0; j < 4; j++) { this->CurrentRenderer->AddActor(this->Handle[j]); this->Handle[j]->SetProperty(this->HandleProperty); } // add the normal vector this->CurrentRenderer->AddActor(this->LineActor); this->LineActor->SetProperty(this->HandleProperty); this->CurrentRenderer->AddActor(this->ConeActor); this->ConeActor->SetProperty(this->HandleProperty); this->CurrentRenderer->AddActor(this->LineActor2); this->LineActor2->SetProperty(this->HandleProperty); this->CurrentRenderer->AddActor(this->ConeActor2); this->ConeActor2->SetProperty(this->HandleProperty); this->SelectRepresentation(); this->RegisterPickers(); this->InvokeEvent(vtkCommand::EnableEvent, nullptr); } else // disabling---------------------------------------------------------- { vtkDebugMacro(<< "Disabling plane widget"); if (!this->Enabled) // already disabled, just return { return; } this->Enabled = 0; // don't listen for events any more this->Interactor->RemoveObserver(this->EventCallbackCommand); // turn off the plane this->CurrentRenderer->RemoveActor(this->PlaneActor); // turn off the handles for (int i = 0; i < 4; i++) { this->CurrentRenderer->RemoveActor(this->Handle[i]); } // turn off the normal vector this->CurrentRenderer->RemoveActor(this->LineActor); this->CurrentRenderer->RemoveActor(this->ConeActor); this->CurrentRenderer->RemoveActor(this->LineActor2); this->CurrentRenderer->RemoveActor(this->ConeActor2); this->CurrentHandle = nullptr; this->InvokeEvent(vtkCommand::DisableEvent, nullptr); this->SetCurrentRenderer(nullptr); this->UnRegisterPickers(); } this->Interactor->Render(); } //------------------------------------------------------------------------------ void vtkPlaneWidget::RegisterPickers() { vtkPickingManager* pm = this->GetPickingManager(); if (!pm) { return; } pm->AddPicker(this->HandlePicker, this); pm->AddPicker(this->PlanePicker, this); } void vtkPlaneWidget::ProcessEvents( vtkObject* vtkNotUsed(object), unsigned long event, void* clientdata, void* vtkNotUsed(calldata)) { vtkPlaneWidget* self = reinterpret_cast(clientdata); // okay, let's do the right thing switch (event) { case vtkCommand::LeftButtonPressEvent: self->OnLeftButtonDown(); break; case vtkCommand::LeftButtonReleaseEvent: self->OnLeftButtonUp(); break; case vtkCommand::MiddleButtonPressEvent: self->OnMiddleButtonDown(); break; case vtkCommand::MiddleButtonReleaseEvent: self->OnMiddleButtonUp(); break; case vtkCommand::RightButtonPressEvent: self->OnRightButtonDown(); break; case vtkCommand::RightButtonReleaseEvent: self->OnRightButtonUp(); break; case vtkCommand::MouseMoveEvent: self->OnMouseMove(); break; case vtkCommand::StartPinchEvent: self->OnStartPinch(); break; case vtkCommand::PinchEvent: self->OnPinch(); break; case vtkCommand::EndPinchEvent: self->OnEndPinch(); break; } } void vtkPlaneWidget::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); if (this->HandleProperty) { os << indent << "Handle Property: " << this->HandleProperty << "\n"; } else { os << indent << "Handle Property: (none)\n"; } if (this->SelectedHandleProperty) { os << indent << "Selected Handle Property: " << this->SelectedHandleProperty << "\n"; } else { os << indent << "SelectedHandle Property: (none)\n"; } if (this->PlaneProperty) { os << indent << "Plane Property: " << this->PlaneProperty << "\n"; } else { os << indent << "Plane Property: (none)\n"; } if (this->SelectedPlaneProperty) { os << indent << "Selected Plane Property: " << this->SelectedPlaneProperty << "\n"; } else { os << indent << "Selected Plane Property: (none)\n"; } os << indent << "Plane Representation: "; if (this->Representation == VTK_PLANE_WIREFRAME) { os << "Wireframe\n"; } else if (this->Representation == VTK_PLANE_SURFACE) { os << "Surface\n"; } else //( this->Representation == VTK_PLANE_OUTLINE ) { os << "Outline\n"; } os << indent << "Normal To X Axis: " << (this->NormalToXAxis ? "On" : "Off") << "\n"; os << indent << "Normal To Y Axis: " << (this->NormalToYAxis ? "On" : "Off") << "\n"; os << indent << "Normal To Z Axis: " << (this->NormalToZAxis ? "On" : "Off") << "\n"; int res = this->PlaneSource->GetXResolution(); double* o = this->PlaneSource->GetOrigin(); double* pt1 = this->PlaneSource->GetPoint1(); double* pt2 = this->PlaneSource->GetPoint2(); os << indent << "Resolution: " << res << "\n"; os << indent << "Origin: (" << o[0] << ", " << o[1] << ", " << o[2] << ")\n"; os << indent << "Point 1: (" << pt1[0] << ", " << pt1[1] << ", " << pt1[2] << ")\n"; os << indent << "Point 2: (" << pt2[0] << ", " << pt2[1] << ", " << pt2[2] << ")\n"; } void vtkPlaneWidget::PositionHandles() { double* o = this->PlaneSource->GetOrigin(); double* pt1 = this->PlaneSource->GetPoint1(); double* pt2 = this->PlaneSource->GetPoint2(); this->HandleGeometry[0]->SetCenter(o); this->HandleGeometry[1]->SetCenter(pt1); this->HandleGeometry[2]->SetCenter(pt2); double x[3]; x[0] = pt1[0] + pt2[0] - o[0]; x[1] = pt1[1] + pt2[1] - o[1]; x[2] = pt1[2] + pt2[2] - o[2]; this->HandleGeometry[3]->SetCenter(x); // far corner // set up the outline if (this->Representation == VTK_PLANE_OUTLINE) { this->PlaneOutline->GetPoints()->SetPoint(0, o); this->PlaneOutline->GetPoints()->SetPoint(1, pt1); this->PlaneOutline->GetPoints()->SetPoint(2, x); this->PlaneOutline->GetPoints()->SetPoint(3, pt2); this->PlaneOutline->GetPoints()->Modified(); } this->SelectRepresentation(); // Create the normal vector double center[3]; this->PlaneSource->GetCenter(center); this->LineSource->SetPoint1(center); this->LineSource2->SetPoint1(center); double p2[3]; this->PlaneSource->GetNormal(this->Normal); vtkMath::Normalize(this->Normal); double d = sqrt(vtkMath::Distance2BetweenPoints( this->PlaneSource->GetPoint1(), this->PlaneSource->GetPoint2())); p2[0] = center[0] + 0.35 * d * this->Normal[0]; p2[1] = center[1] + 0.35 * d * this->Normal[1]; p2[2] = center[2] + 0.35 * d * this->Normal[2]; this->LineSource->SetPoint2(p2); this->ConeSource->SetCenter(p2); this->ConeSource->SetDirection(this->Normal); p2[0] = center[0] - 0.35 * d * this->Normal[0]; p2[1] = center[1] - 0.35 * d * this->Normal[1]; p2[2] = center[2] - 0.35 * d * this->Normal[2]; this->LineSource2->SetPoint2(p2); this->ConeSource2->SetCenter(p2); this->ConeSource2->SetDirection(this->Normal); } int vtkPlaneWidget::HighlightHandle(vtkProp* prop) { // first unhighlight anything picked if (this->CurrentHandle) { this->CurrentHandle->SetProperty(this->HandleProperty); } this->CurrentHandle = static_cast(prop); if (this->CurrentHandle) { this->ValidPick = 1; this->HandlePicker->GetPickPosition(this->LastPickPosition); this->CurrentHandle->SetProperty(this->SelectedHandleProperty); for (int i = 0; i < 4; i++) // find handle { if (this->CurrentHandle == this->Handle[i]) { return i; } } } return -1; } void vtkPlaneWidget::HighlightNormal(int highlight) { if (highlight) { this->ValidPick = 1; this->PlanePicker->GetPickPosition(this->LastPickPosition); this->LineActor->SetProperty(this->SelectedHandleProperty); this->ConeActor->SetProperty(this->SelectedHandleProperty); this->LineActor2->SetProperty(this->SelectedHandleProperty); this->ConeActor2->SetProperty(this->SelectedHandleProperty); } else { this->LineActor->SetProperty(this->HandleProperty); this->ConeActor->SetProperty(this->HandleProperty); this->LineActor2->SetProperty(this->HandleProperty); this->ConeActor2->SetProperty(this->HandleProperty); } } void vtkPlaneWidget::HighlightPlane(int highlight) { if (highlight) { this->ValidPick = 1; this->PlanePicker->GetPickPosition(this->LastPickPosition); this->PlaneActor->SetProperty(this->SelectedPlaneProperty); } else { this->PlaneActor->SetProperty(this->PlaneProperty); } } void vtkPlaneWidget::OnStartPinch() { int X = this->Interactor->GetEventPosition()[0]; int Y = this->Interactor->GetEventPosition()[1]; // Okay, make sure that the pick is in the current renderer if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y)) { this->State = vtkPlaneWidget::Outside; return; } // Okay, we can process this. try to pick the plane. vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->PlanePicker); if (path != nullptr) { this->State = vtkPlaneWidget::Pinching; this->HighlightPlane(1); this->StartInteraction(); this->InvokeEvent(vtkCommand::StartInteractionEvent, nullptr); } } void vtkPlaneWidget::OnPinch() { if (this->State != vtkPlaneWidget::Pinching) { return; } double sf = this->Interactor->GetScale() / this->Interactor->GetLastScale(); double* o = this->PlaneSource->GetOrigin(); double* pt1 = this->PlaneSource->GetPoint1(); double* pt2 = this->PlaneSource->GetPoint2(); double center[3]; center[0] = 0.5 * (pt1[0] + pt2[0]); center[1] = 0.5 * (pt1[1] + pt2[1]); center[2] = 0.5 * (pt1[2] + pt2[2]); // Move the corner points double origin[3], point1[3], point2[3]; for (int i = 0; i < 3; i++) { origin[i] = sf * (o[i] - center[i]) + center[i]; point1[i] = sf * (pt1[i] - center[i]) + center[i]; point2[i] = sf * (pt2[i] - center[i]) + center[i]; } this->PlaneSource->SetOrigin(origin); this->PlaneSource->SetPoint1(point1); this->PlaneSource->SetPoint2(point2); this->PlaneSource->Update(); this->PositionHandles(); this->EventCallbackCommand->SetAbortFlag(1); this->InvokeEvent(vtkCommand::InteractionEvent, nullptr); this->Interactor->Render(); } void vtkPlaneWidget::OnEndPinch() { if (this->State != vtkPlaneWidget::Pinching) { return; } this->State = vtkPlaneWidget::Start; this->HighlightHandle(nullptr); this->HighlightPlane(0); this->HighlightNormal(0); this->SizeHandles(); this->EventCallbackCommand->SetAbortFlag(1); this->EndInteraction(); this->InvokeEvent(vtkCommand::EndInteractionEvent, nullptr); this->Interactor->Render(); } void vtkPlaneWidget::OnLeftButtonDown() { int X = this->Interactor->GetEventPosition()[0]; int Y = this->Interactor->GetEventPosition()[1]; // Okay, make sure that the pick is in the current renderer if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y)) { this->State = vtkPlaneWidget::Outside; return; } // Okay, we can process this. Try to pick handles first; // if no handles picked, then try to pick the plane. vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->HandlePicker); if (path != nullptr) { this->State = vtkPlaneWidget::Moving; this->HighlightHandle(path->GetFirstNode()->GetViewProp()); } else { path = this->GetAssemblyPath(X, Y, 0., this->PlanePicker); if (path != nullptr) { vtkProp* prop = path->GetFirstNode()->GetViewProp(); if (prop == this->ConeActor || prop == this->LineActor || prop == this->ConeActor2 || prop == this->LineActor2) { this->State = vtkPlaneWidget::Rotating; this->HighlightNormal(1); } else if (this->Interactor->GetControlKey()) { this->State = vtkPlaneWidget::Spinning; this->HighlightNormal(1); } else { this->State = vtkPlaneWidget::Moving; this->HighlightPlane(1); } } else { this->State = vtkPlaneWidget::Outside; this->HighlightHandle(nullptr); return; } } this->EventCallbackCommand->SetAbortFlag(1); this->StartInteraction(); this->InvokeEvent(vtkCommand::StartInteractionEvent, nullptr); this->Interactor->Render(); } void vtkPlaneWidget::OnLeftButtonUp() { if (this->State == vtkPlaneWidget::Outside || this->State == vtkPlaneWidget::Start) { return; } this->State = vtkPlaneWidget::Start; this->HighlightHandle(nullptr); this->HighlightPlane(0); this->HighlightNormal(0); this->SizeHandles(); this->EventCallbackCommand->SetAbortFlag(1); this->EndInteraction(); this->InvokeEvent(vtkCommand::EndInteractionEvent, nullptr); this->Interactor->Render(); } void vtkPlaneWidget::OnMiddleButtonDown() { int X = this->Interactor->GetEventPosition()[0]; int Y = this->Interactor->GetEventPosition()[1]; // Okay, make sure that the pick is in the current renderer if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y)) { this->State = vtkPlaneWidget::Outside; return; } // Okay, we can process this. If anything is picked, then we // can start pushing the plane. vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->HandlePicker); if (path != nullptr) { this->State = vtkPlaneWidget::Pushing; this->HighlightPlane(1); this->HighlightNormal(1); this->HighlightHandle(path->GetFirstNode()->GetViewProp()); } else { path = this->GetAssemblyPath(X, Y, 0., this->PlanePicker); if (path == nullptr) // nothing picked { this->State = vtkPlaneWidget::Outside; return; } else { this->State = vtkPlaneWidget::Pushing; this->HighlightNormal(1); this->HighlightPlane(1); } } this->EventCallbackCommand->SetAbortFlag(1); this->StartInteraction(); this->InvokeEvent(vtkCommand::StartInteractionEvent, nullptr); this->Interactor->Render(); } void vtkPlaneWidget::OnMiddleButtonUp() { if (this->State == vtkPlaneWidget::Outside || this->State == vtkPlaneWidget::Start) { return; } this->State = vtkPlaneWidget::Start; this->HighlightPlane(0); this->HighlightNormal(0); this->HighlightHandle(nullptr); this->SizeHandles(); this->EventCallbackCommand->SetAbortFlag(1); this->EndInteraction(); this->InvokeEvent(vtkCommand::EndInteractionEvent, nullptr); this->Interactor->Render(); } void vtkPlaneWidget::OnRightButtonDown() { int X = this->Interactor->GetEventPosition()[0]; int Y = this->Interactor->GetEventPosition()[1]; // Okay, make sure that the pick is in the current renderer if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y)) { this->State = vtkPlaneWidget::Outside; return; } // Okay, we can process this. Try to pick handles first; // if no handles picked, then pick the bounding box. vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->HandlePicker); if (path != nullptr) { this->State = vtkPlaneWidget::Scaling; this->HighlightPlane(1); this->HighlightHandle(path->GetFirstNode()->GetViewProp()); } else // see if we picked the plane or a normal { path = this->GetAssemblyPath(X, Y, 0., this->PlanePicker); if (path == nullptr) { this->State = vtkPlaneWidget::Outside; return; } else { this->State = vtkPlaneWidget::Scaling; this->HighlightPlane(1); } } this->EventCallbackCommand->SetAbortFlag(1); this->StartInteraction(); this->InvokeEvent(vtkCommand::StartInteractionEvent, nullptr); this->Interactor->Render(); } void vtkPlaneWidget::OnRightButtonUp() { if (this->State == vtkPlaneWidget::Outside || this->State == vtkPlaneWidget::Start) { return; } this->State = vtkPlaneWidget::Start; this->HighlightPlane(0); this->SizeHandles(); this->EventCallbackCommand->SetAbortFlag(1); this->EndInteraction(); this->InvokeEvent(vtkCommand::EndInteractionEvent, nullptr); this->Interactor->Render(); } void vtkPlaneWidget::OnMouseMove() { // See whether we're active if (this->State == vtkPlaneWidget::Outside || this->State == vtkPlaneWidget::Start) { return; } int X = this->Interactor->GetEventPosition()[0]; int Y = this->Interactor->GetEventPosition()[1]; // Do different things depending on state // Calculations everybody does double focalPoint[4], pickPoint[4], prevPickPoint[4]; double z, vpn[3]; vtkCamera* camera = this->CurrentRenderer->GetActiveCamera(); if (!camera) { return; } // Compute the two points defining the motion vector this->ComputeWorldToDisplay( this->LastPickPosition[0], this->LastPickPosition[1], this->LastPickPosition[2], focalPoint); z = focalPoint[2]; this->ComputeDisplayToWorld(double(this->Interactor->GetLastEventPosition()[0]), double(this->Interactor->GetLastEventPosition()[1]), z, prevPickPoint); this->ComputeDisplayToWorld(double(X), double(Y), z, pickPoint); // Process the motion if (this->State == vtkPlaneWidget::Moving) { // Okay to process if (this->CurrentHandle) { if (this->CurrentHandle == this->Handle[0]) { this->MoveOrigin(prevPickPoint, pickPoint); } else if (this->CurrentHandle == this->Handle[1]) { this->MovePoint1(prevPickPoint, pickPoint); } else if (this->CurrentHandle == this->Handle[2]) { this->MovePoint2(prevPickPoint, pickPoint); } else if (this->CurrentHandle == this->Handle[3]) { this->MovePoint3(prevPickPoint, pickPoint); } } else // must be moving the plane { this->Translate(prevPickPoint, pickPoint); } } else if (this->State == vtkPlaneWidget::Scaling) { this->Scale(prevPickPoint, pickPoint, X, Y); } else if (this->State == vtkPlaneWidget::Pushing) { this->Push(prevPickPoint, pickPoint); } else if (this->State == vtkPlaneWidget::Rotating) { camera->GetViewPlaneNormal(vpn); this->Rotate(X, Y, prevPickPoint, pickPoint, vpn); } else if (this->State == vtkPlaneWidget::Spinning) { this->Spin(prevPickPoint, pickPoint); } // Interact, if desired this->EventCallbackCommand->SetAbortFlag(1); this->InvokeEvent(vtkCommand::InteractionEvent, nullptr); this->Interactor->Render(); } void vtkPlaneWidget::MoveOrigin(double* p1, double* p2) { // Get the plane definition double* o = this->PlaneSource->GetOrigin(); double* pt1 = this->PlaneSource->GetPoint1(); double* pt2 = this->PlaneSource->GetPoint2(); // Get the vector of motion double v[3]; v[0] = p2[0] - p1[0]; v[1] = p2[1] - p1[1]; v[2] = p2[2] - p1[2]; double vN = vtkMath::Norm(v); // if there is no motion then return if (vN < VTK_PLANE_ZERO_THRESHOLD) { return; } // The point opposite the origin (pt3) stays fixed double pt3[3]; pt3[0] = o[0] + (pt1[0] - o[0]) + (pt2[0] - o[0]); pt3[1] = o[1] + (pt1[1] - o[1]) + (pt2[1] - o[1]); pt3[2] = o[2] + (pt1[2] - o[2]) + (pt2[2] - o[2]); // Define vectors from point pt3 double p13[3], p23[3]; p13[0] = pt1[0] - pt3[0]; p13[1] = pt1[1] - pt3[1]; p13[2] = pt1[2] - pt3[2]; p23[0] = pt2[0] - pt3[0]; p23[1] = pt2[1] - pt3[1]; p23[2] = pt2[2] - pt3[2]; double n13 = vtkMath::Norm(p13); double n23 = vtkMath::Norm(p23); if ((n13 < VTK_PLANE_ZERO_THRESHOLD) || (n23 < VTK_PLANE_ZERO_THRESHOLD)) { return; } // Project v onto these vector to determine the amount of motion // Scale it by the relative size of the motion to the vector length double d1 = (vN / n13) * vtkMath::Dot(v, p13) / (vN * n13); double d2 = (vN / n23) * vtkMath::Dot(v, p23) / (vN * n23); double point1[3], point2[3], origin[3]; for (int i = 0; i < 3; i++) { point1[i] = pt3[i] + (1.0 + d1) * p13[i]; point2[i] = pt3[i] + (1.0 + d2) * p23[i]; origin[i] = pt3[i] + (1.0 + d1) * p13[i] + (1.0 + d2) * p23[i]; } this->PlaneSource->SetOrigin(origin); this->PlaneSource->SetPoint1(point1); this->PlaneSource->SetPoint2(point2); this->PlaneSource->Update(); this->PositionHandles(); } void vtkPlaneWidget::MovePoint1(double* p1, double* p2) { // Get the plane definition double* o = this->PlaneSource->GetOrigin(); double* pt1 = this->PlaneSource->GetPoint1(); double* pt2 = this->PlaneSource->GetPoint2(); // Get the vector of motion double v[3]; v[0] = p2[0] - p1[0]; v[1] = p2[1] - p1[1]; v[2] = p2[2] - p1[2]; double vN = vtkMath::Norm(v); // if there is no motion then return if (vN < VTK_PLANE_ZERO_THRESHOLD) { return; } // Need the point opposite the origin (pt3) double pt3[3]; pt3[0] = o[0] + (pt1[0] - o[0]) + (pt2[0] - o[0]); pt3[1] = o[1] + (pt1[1] - o[1]) + (pt2[1] - o[1]); pt3[2] = o[2] + (pt1[2] - o[2]) + (pt2[2] - o[2]); // Define vectors from point pt2 double p32[3], p02[3]; p02[0] = o[0] - pt2[0]; p02[1] = o[1] - pt2[1]; p02[2] = o[2] - pt2[2]; p32[0] = pt3[0] - pt2[0]; p32[1] = pt3[1] - pt2[1]; p32[2] = pt3[2] - pt2[2]; double n02 = vtkMath::Norm(p02); double n32 = vtkMath::Norm(p32); if ((n02 < VTK_PLANE_ZERO_THRESHOLD) || (n32 < VTK_PLANE_ZERO_THRESHOLD)) { return; } // Project v onto these vector to determine the amount of motion // Scale it by the relative size of the motion to the vector length double d1 = (vN / n02) * vtkMath::Dot(v, p02) / (vN * n02); double d2 = (vN / n32) * vtkMath::Dot(v, p32) / (vN * n32); double point1[3], origin[3]; for (int i = 0; i < 3; i++) { origin[i] = pt2[i] + (1.0 + d1) * p02[i]; point1[i] = pt2[i] + (1.0 + d1) * p02[i] + (1.0 + d2) * p32[i]; } this->PlaneSource->SetOrigin(origin); this->PlaneSource->SetPoint1(point1); this->PlaneSource->Update(); this->PositionHandles(); } void vtkPlaneWidget::MovePoint2(double* p1, double* p2) { // Get the plane definition double* o = this->PlaneSource->GetOrigin(); double* pt1 = this->PlaneSource->GetPoint1(); double* pt2 = this->PlaneSource->GetPoint2(); // Get the vector of motion double v[3]; v[0] = p2[0] - p1[0]; v[1] = p2[1] - p1[1]; v[2] = p2[2] - p1[2]; double vN = vtkMath::Norm(v); // if there is no motion then return if (vN < VTK_PLANE_ZERO_THRESHOLD) { return; } // The point opposite point2 (pt1) stays fixed double pt3[3]; pt3[0] = o[0] + (pt1[0] - o[0]) + (pt2[0] - o[0]); pt3[1] = o[1] + (pt1[1] - o[1]) + (pt2[1] - o[1]); pt3[2] = o[2] + (pt1[2] - o[2]) + (pt2[2] - o[2]); // Define vectors from point pt1 double p01[3], p31[3]; p31[0] = pt3[0] - pt1[0]; p31[1] = pt3[1] - pt1[1]; p31[2] = pt3[2] - pt1[2]; p01[0] = o[0] - pt1[0]; p01[1] = o[1] - pt1[1]; p01[2] = o[2] - pt1[2]; double n31 = vtkMath::Norm(p31); double n01 = vtkMath::Norm(p01); if ((n31 < VTK_PLANE_ZERO_THRESHOLD) || (n01 < VTK_PLANE_ZERO_THRESHOLD)) { return; } // Project v onto these vector to determine the amount of motion // Scale it by the relative size of the motion to the vector length double d1 = (vN / n31) * vtkMath::Dot(v, p31) / (vN * n31); double d2 = (vN / n01) * vtkMath::Dot(v, p01) / (vN * n01); double point2[3], origin[3]; for (int i = 0; i < 3; i++) { point2[i] = pt1[i] + (1.0 + d1) * p31[i] + (1.0 + d2) * p01[i]; origin[i] = pt1[i] + (1.0 + d2) * p01[i]; } this->PlaneSource->SetOrigin(origin); this->PlaneSource->SetPoint2(point2); this->PlaneSource->Update(); this->PositionHandles(); } void vtkPlaneWidget::MovePoint3(double* p1, double* p2) { // Get the plane definition double* o = this->PlaneSource->GetOrigin(); double* pt1 = this->PlaneSource->GetPoint1(); double* pt2 = this->PlaneSource->GetPoint2(); // Get the vector of motion double v[3]; v[0] = p2[0] - p1[0]; v[1] = p2[1] - p1[1]; v[2] = p2[2] - p1[2]; double vN = vtkMath::Norm(v); // if there is no motion then return if (vN < VTK_PLANE_ZERO_THRESHOLD) { return; } // Define vectors from point pt3 double p10[3], p20[3]; p10[0] = pt1[0] - o[0]; p10[1] = pt1[1] - o[1]; p10[2] = pt1[2] - o[2]; p20[0] = pt2[0] - o[0]; p20[1] = pt2[1] - o[1]; p20[2] = pt2[2] - o[2]; double n10 = vtkMath::Norm(p10); double n20 = vtkMath::Norm(p20); if ((n10 < VTK_PLANE_ZERO_THRESHOLD) || (n20 < VTK_PLANE_ZERO_THRESHOLD)) { return; } // Project v onto these vector to determine the amount of motion // Scale it by the relative size of the motion to the vector length double d1 = (vN / n10) * vtkMath::Dot(v, p10) / (vN * n10); double d2 = (vN / n20) * vtkMath::Dot(v, p20) / (vN * n20); double point1[3], point2[3]; for (int i = 0; i < 3; i++) { point1[i] = o[i] + (1.0 + d1) * p10[i]; point2[i] = o[i] + (1.0 + d2) * p20[i]; } this->PlaneSource->SetPoint1(point1); this->PlaneSource->SetPoint2(point2); this->PlaneSource->Update(); this->PositionHandles(); } void vtkPlaneWidget::Rotate(int X, int Y, double* p1, double* p2, double* vpn) { double* o = this->PlaneSource->GetOrigin(); double* pt1 = this->PlaneSource->GetPoint1(); double* pt2 = this->PlaneSource->GetPoint2(); double* center = this->PlaneSource->GetCenter(); double v[3]; // vector of motion double axis[3]; // axis of rotation double theta; // rotation angle // mouse motion vector in world space v[0] = p2[0] - p1[0]; v[1] = p2[1] - p1[1]; v[2] = p2[2] - p1[2]; // Create axis of rotation and angle of rotation vtkMath::Cross(vpn, v, axis); if (vtkMath::Normalize(axis) == 0.0) { return; } const int* size = this->CurrentRenderer->GetSize(); double l2 = (X - this->Interactor->GetLastEventPosition()[0]) * (X - this->Interactor->GetLastEventPosition()[0]) + (Y - this->Interactor->GetLastEventPosition()[1]) * (Y - this->Interactor->GetLastEventPosition()[1]); theta = 360.0 * sqrt(l2 / (size[0] * size[0] + size[1] * size[1])); // Manipulate the transform to reflect the rotation this->Transform->Identity(); this->Transform->Translate(center[0], center[1], center[2]); this->Transform->RotateWXYZ(theta, axis); this->Transform->Translate(-center[0], -center[1], -center[2]); // Set the corners double oNew[3], pt1New[3], pt2New[3]; this->Transform->TransformPoint(o, oNew); this->Transform->TransformPoint(pt1, pt1New); this->Transform->TransformPoint(pt2, pt2New); this->PlaneSource->SetOrigin(oNew); this->PlaneSource->SetPoint1(pt1New); this->PlaneSource->SetPoint2(pt2New); this->PlaneSource->Update(); this->PositionHandles(); } void vtkPlaneWidget::Spin(double* p1, double* p2) { // Mouse motion vector in world space double v[3]; v[0] = p2[0] - p1[0]; v[1] = p2[1] - p1[1]; v[2] = p2[2] - p1[2]; double* normal = this->PlaneSource->GetNormal(); // Axis of rotation double axis[3] = { normal[0], normal[1], normal[2] }; vtkMath::Normalize(axis); double* o = this->PlaneSource->GetOrigin(); double* pt1 = this->PlaneSource->GetPoint1(); double* pt2 = this->PlaneSource->GetPoint2(); double* center = this->PlaneSource->GetCenter(); // Radius vector (from center to cursor position) double rv[3] = { p2[0] - center[0], p2[1] - center[1], p2[2] - center[2] }; // Distance between center and cursor location double rs = vtkMath::Normalize(rv); // Spin direction double ax_cross_rv[3]; vtkMath::Cross(axis, rv, ax_cross_rv); // Spin angle double theta = vtkMath::DegreesFromRadians(vtkMath::Dot(v, ax_cross_rv) / rs); // Manipulate the transform to reflect the rotation this->Transform->Identity(); this->Transform->Translate(center[0], center[1], center[2]); this->Transform->RotateWXYZ(theta, axis); this->Transform->Translate(-center[0], -center[1], -center[2]); // Set the corners double oNew[3], pt1New[3], pt2New[3]; this->Transform->TransformPoint(o, oNew); this->Transform->TransformPoint(pt1, pt1New); this->Transform->TransformPoint(pt2, pt2New); this->PlaneSource->SetOrigin(oNew); this->PlaneSource->SetPoint1(pt1New); this->PlaneSource->SetPoint2(pt2New); this->PlaneSource->Update(); this->PositionHandles(); } // Loop through all points and translate them void vtkPlaneWidget::Translate(double* p1, double* p2) { // Get the motion vector double v[3]; v[0] = p2[0] - p1[0]; v[1] = p2[1] - p1[1]; v[2] = p2[2] - p1[2]; // int res = this->PlaneSource->GetXResolution(); double* o = this->PlaneSource->GetOrigin(); double* pt1 = this->PlaneSource->GetPoint1(); double* pt2 = this->PlaneSource->GetPoint2(); double origin[3], point1[3], point2[3]; for (int i = 0; i < 3; i++) { origin[i] = o[i] + v[i]; point1[i] = pt1[i] + v[i]; point2[i] = pt2[i] + v[i]; } this->PlaneSource->SetOrigin(origin); this->PlaneSource->SetPoint1(point1); this->PlaneSource->SetPoint2(point2); this->PlaneSource->Update(); this->PositionHandles(); } void vtkPlaneWidget::Scale(double* p1, double* p2, int vtkNotUsed(X), int Y) { // Get the motion vector double v[3]; v[0] = p2[0] - p1[0]; v[1] = p2[1] - p1[1]; v[2] = p2[2] - p1[2]; // int res = this->PlaneSource->GetXResolution(); double* o = this->PlaneSource->GetOrigin(); double* pt1 = this->PlaneSource->GetPoint1(); double* pt2 = this->PlaneSource->GetPoint2(); double center[3]; center[0] = 0.5 * (pt1[0] + pt2[0]); center[1] = 0.5 * (pt1[1] + pt2[1]); center[2] = 0.5 * (pt1[2] + pt2[2]); // Compute the scale factor double sf = vtkMath::Norm(v) / sqrt(vtkMath::Distance2BetweenPoints(pt1, pt2)); if (Y > this->Interactor->GetLastEventPosition()[1]) { sf = 1.0 + sf; } else { sf = 1.0 - sf; } // Move the corner points double origin[3], point1[3], point2[3]; for (int i = 0; i < 3; i++) { origin[i] = sf * (o[i] - center[i]) + center[i]; point1[i] = sf * (pt1[i] - center[i]) + center[i]; point2[i] = sf * (pt2[i] - center[i]) + center[i]; } this->PlaneSource->SetOrigin(origin); this->PlaneSource->SetPoint1(point1); this->PlaneSource->SetPoint2(point2); this->PlaneSource->Update(); this->PositionHandles(); } void vtkPlaneWidget::Push(double* p1, double* p2) { // Get the motion vector double v[3]; v[0] = p2[0] - p1[0]; v[1] = p2[1] - p1[1]; v[2] = p2[2] - p1[2]; this->PlaneSource->Push(vtkMath::Dot(v, this->Normal)); this->PlaneSource->Update(); this->PositionHandles(); } void vtkPlaneWidget::CreateDefaultProperties() { // Handle properties this->HandleProperty = vtkProperty::New(); this->HandleProperty->SetColor(1, 1, 1); this->SelectedHandleProperty = vtkProperty::New(); this->SelectedHandleProperty->SetColor(1, 0, 0); // Plane properties this->PlaneProperty = vtkProperty::New(); this->PlaneProperty->SetAmbient(1.0); this->PlaneProperty->SetAmbientColor(1.0, 1.0, 1.0); this->SelectedPlaneProperty = vtkProperty::New(); this->SelectRepresentation(); this->SelectedPlaneProperty->SetAmbient(1.0); this->SelectedPlaneProperty->SetAmbientColor(0.0, 1.0, 0.0); } void vtkPlaneWidget::PlaceWidget(double bds[6]) { int i; double bounds[6], center[3]; this->AdjustBounds(bds, bounds, center); if (this->GetInput() || this->Prop3D) { if (this->NormalToYAxis) { this->PlaneSource->SetOrigin(bounds[0], center[1], bounds[4]); this->PlaneSource->SetPoint1(bounds[1], center[1], bounds[4]); this->PlaneSource->SetPoint2(bounds[0], center[1], bounds[5]); } else if (this->NormalToZAxis) { this->PlaneSource->SetOrigin(bounds[0], bounds[2], center[2]); this->PlaneSource->SetPoint1(bounds[1], bounds[2], center[2]); this->PlaneSource->SetPoint2(bounds[0], bounds[3], center[2]); } else // default or x-normal { this->PlaneSource->SetOrigin(center[0], bounds[2], bounds[4]); this->PlaneSource->SetPoint1(center[0], bounds[3], bounds[4]); this->PlaneSource->SetPoint2(center[0], bounds[2], bounds[5]); } } this->PlaneSource->Update(); // Position the handles at the end of the planes this->PositionHandles(); for (i = 0; i < 6; i++) { this->InitialBounds[i] = bounds[i]; } if (this->GetInput() || this->Prop3D) { this->InitialLength = sqrt((bounds[1] - bounds[0]) * (bounds[1] - bounds[0]) + (bounds[3] - bounds[2]) * (bounds[3] - bounds[2]) + (bounds[5] - bounds[4]) * (bounds[5] - bounds[4])); } else { // this means we have to make use of the PolyDataSource, so // we just calculate the magnitude of the longest diagonal on // the plane and use that as InitialLength double origin[3], point1[3], point2[3]; this->PlaneSource->GetOrigin(origin); this->PlaneSource->GetPoint1(point1); this->PlaneSource->GetPoint2(point2); double sqr1 = 0, sqr2 = 0; for (i = 0; i < 3; i++) { sqr1 += (point1[i] - origin[i]) * (point1[i] - origin[i]); sqr2 += (point2[i] - origin[i]) * (point2[i] - origin[i]); } this->InitialLength = sqrt(sqr1 + sqr2); } // Set the radius on the sphere handles this->SizeHandles(); } void vtkPlaneWidget::SizeHandles() { double radius = this->vtk3DWidget::SizeHandles(this->HandleSizeFactor); if (this->ValidPick && !this->LastPickValid) { // Adjust factor to preserve old radius. double oldradius = this->HandleGeometry[0]->GetRadius(); if (oldradius != 0 && radius != 0) { this->HandleSizeFactor = oldradius / radius; radius = oldradius; } } this->LastPickValid = this->ValidPick; for (int i = 0; i < 4; i++) { this->HandleGeometry[i]->SetRadius(radius); } // Set the height and radius of the cone this->ConeSource->SetHeight(2.0 * radius); this->ConeSource->SetRadius(radius); this->ConeSource2->SetHeight(2.0 * radius); this->ConeSource2->SetRadius(radius); } void vtkPlaneWidget::SelectRepresentation() { if (!this->CurrentRenderer) { return; } if (this->Representation == VTK_PLANE_OFF) { this->CurrentRenderer->RemoveActor(this->PlaneActor); } else if (this->Representation == VTK_PLANE_OUTLINE) { this->CurrentRenderer->RemoveActor(this->PlaneActor); this->CurrentRenderer->AddActor(this->PlaneActor); this->PlaneMapper->SetInputData(this->PlaneOutline); this->PlaneActor->GetProperty()->SetRepresentationToWireframe(); } else if (this->Representation == VTK_PLANE_SURFACE) { this->CurrentRenderer->RemoveActor(this->PlaneActor); this->CurrentRenderer->AddActor(this->PlaneActor); this->PlaneMapper->SetInputConnection(this->PlaneSource->GetOutputPort()); this->PlaneActor->GetProperty()->SetRepresentationToSurface(); } else //( this->Representation == VTK_PLANE_WIREFRAME ) { this->CurrentRenderer->RemoveActor(this->PlaneActor); this->CurrentRenderer->AddActor(this->PlaneActor); this->PlaneMapper->SetInputConnection(this->PlaneSource->GetOutputPort()); this->PlaneActor->GetProperty()->SetRepresentationToWireframe(); } } // Description: // Set/Get the resolution (number of subdivisions) of the plane. void vtkPlaneWidget::SetResolution(int r) { this->PlaneSource->SetXResolution(r); this->PlaneSource->SetYResolution(r); } int vtkPlaneWidget::GetResolution() { return this->PlaneSource->GetXResolution(); } // Description: // Set/Get the origin of the plane. void vtkPlaneWidget::SetOrigin(double x, double y, double z) { this->PlaneSource->SetOrigin(x, y, z); this->PositionHandles(); } void vtkPlaneWidget::SetOrigin(double x[3]) { this->SetOrigin(x[0], x[1], x[2]); } double* vtkPlaneWidget::GetOrigin() { return this->PlaneSource->GetOrigin(); } void vtkPlaneWidget::GetOrigin(double xyz[3]) { this->PlaneSource->GetOrigin(xyz); } // Description: // Set/Get the position of the point defining the first axis of the plane. void vtkPlaneWidget::SetPoint1(double x, double y, double z) { this->PlaneSource->SetPoint1(x, y, z); this->PositionHandles(); } void vtkPlaneWidget::SetPoint1(double x[3]) { this->SetPoint1(x[0], x[1], x[2]); } double* vtkPlaneWidget::GetPoint1() { return this->PlaneSource->GetPoint1(); } void vtkPlaneWidget::GetPoint1(double xyz[3]) { this->PlaneSource->GetPoint1(xyz); } // Description: // Set/Get the position of the point defining the second axis of the plane. void vtkPlaneWidget::SetPoint2(double x, double y, double z) { this->PlaneSource->SetPoint2(x, y, z); this->PositionHandles(); } void vtkPlaneWidget::SetPoint2(double x[3]) { this->SetPoint2(x[0], x[1], x[2]); } double* vtkPlaneWidget::GetPoint2() { return this->PlaneSource->GetPoint2(); } void vtkPlaneWidget::GetPoint2(double xyz[3]) { this->PlaneSource->GetPoint2(xyz); } // Description: // Set the center of the plane. void vtkPlaneWidget::SetCenter(double x, double y, double z) { this->PlaneSource->SetCenter(x, y, z); this->PositionHandles(); } // Description: // Set the center of the plane. void vtkPlaneWidget::SetCenter(double c[3]) { this->SetCenter(c[0], c[1], c[2]); } // Description: // Get the center of the plane. double* vtkPlaneWidget::GetCenter() { return this->PlaneSource->GetCenter(); } void vtkPlaneWidget::GetCenter(double xyz[3]) { this->PlaneSource->GetCenter(xyz); } // Description: // Set the normal to the plane. void vtkPlaneWidget::SetNormal(double x, double y, double z) { this->PlaneSource->SetNormal(x, y, z); this->PositionHandles(); } // Description: // Set the normal to the plane. void vtkPlaneWidget::SetNormal(double n[3]) { this->SetNormal(n[0], n[1], n[2]); } // Description: // Get the normal to the plane. double* vtkPlaneWidget::GetNormal() { return this->PlaneSource->GetNormal(); } void vtkPlaneWidget::GetNormal(double xyz[3]) { this->PlaneSource->GetNormal(xyz); } void vtkPlaneWidget::GetPolyData(vtkPolyData* pd) { pd->ShallowCopy(this->PlaneSource->GetOutput()); } vtkPolyDataAlgorithm* vtkPlaneWidget::GetPolyDataAlgorithm() { return this->PlaneSource; } void vtkPlaneWidget::GetPlane(vtkPlane* plane) { if (plane == nullptr) { return; } plane->SetNormal(this->GetNormal()); plane->SetOrigin(this->GetCenter()); } void vtkPlaneWidget::UpdatePlacement() { this->PlaneSource->Update(); this->PositionHandles(); }