// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // SPDX-License-Identifier: BSD-3-Clause #include "vtkOrientationRepresentation.h" #include "vtkActor.h" #include "vtkAppendPolyData.h" #include "vtkArrowSource.h" #include "vtkAssemblyPath.h" #include "vtkBox.h" #include "vtkCallbackCommand.h" #include "vtkCamera.h" #include "vtkCellPicker.h" #include "vtkEventData.h" #include "vtkInteractorObserver.h" #include "vtkMath.h" #include "vtkObjectFactory.h" #include "vtkPickingManager.h" #include "vtkPolyDataMapper.h" #include "vtkPolyDataNormals.h" #include "vtkProperty.h" #include "vtkRenderer.h" #include "vtkSuperquadricSource.h" #include "vtkTransform.h" #include "vtkTransformFilter.h" #include "vtkWindow.h" #include VTK_ABI_NAMESPACE_BEGIN vtkStandardNewMacro(vtkOrientationRepresentation); namespace { constexpr int NUMBER_OF_TORUS = 3; constexpr int NUMBER_OF_ARROWS = 4 * NUMBER_OF_TORUS; constexpr double X_VECTOR[3] = { 1.0, 0.0, 0.0 }; constexpr double Y_VECTOR[3] = { 0.0, 1.0, 0.0 }; constexpr double Z_VECTOR[3] = { 0.0, 0.0, 1.0 }; constexpr int TORUS_RESOLUTION = 64; constexpr int TORUS_PHI_ROUNDNESS = 0; constexpr double TORUS_CENTERS[NUMBER_OF_TORUS][3] = { { 0.0, 0.0, 0.0 }, { 0.001, 0.001, 0.001 }, { -0.001, -0.001, -0.001 } }; constexpr int ARROW_RESOLUTION = 16; constexpr double ARROW_ROTATION_X[NUMBER_OF_TORUS][2] = { { 0.0, 0.0 }, { 90.0, 90.0 }, { 0.0, 0.0 } }; constexpr double ARROW_ROTATION_Y[NUMBER_OF_TORUS][2] = { { 90.0, -90.0 }, { 0.0, 0.0 }, { 0.0, 0.0 } }; constexpr double ARROW_ROTATION_Z[NUMBER_OF_TORUS][2] = { { 90.0, -90.0 }, { 90.0, -90.0 }, { 0.0, 180.0 } }; } //------------------------------------------------------------------------------ vtkOrientationRepresentation::vtkOrientationRepresentation() { this->InteractionState = vtkOrientationRepresentation::Outside; this->PlaceFactor = 1.0; this->ValidPick = 1; this->BaseTransform->PostMultiply(); this->OrientationTransform->PostMultiply(); // Set up the initial properties this->CreateDefaultProperties(); // Create the torus and arrows this->InitSources(); this->InitTransforms(); for (int i = Axis::X_AXIS; i <= Axis::Z_AXIS; ++i) { Axis axis = static_cast(i); vtkNew torusOrientationTransformFilter; torusOrientationTransformFilter->SetTransform(this->OrientationTransform); torusOrientationTransformFilter->SetInputConnection(this->TorusSources[i]->GetOutputPort()); vtkNew torusBaseTransformFilter; torusBaseTransformFilter->SetTransform(this->BaseTransform); torusBaseTransformFilter->SetInputConnection(torusOrientationTransformFilter->GetOutputPort()); vtkSmartPointer arrows = this->GetArrowsOutput(i); vtkNew arrowsOrientationTransformFilter; arrowsOrientationTransformFilter->SetTransform(this->OrientationTransform); arrowsOrientationTransformFilter->SetInputConnection(arrows->GetOutputPort()); vtkNew arrowsBaseTransformFilter; arrowsBaseTransformFilter->SetTransform(this->BaseTransform); arrowsBaseTransformFilter->SetInputConnection( arrowsOrientationTransformFilter->GetOutputPort()); vtkNew torusMapper; torusMapper->SetInputConnection(torusBaseTransformFilter->GetOutputPort()); vtkNew arrowsMapper; arrowsMapper->SetInputConnection(arrowsBaseTransformFilter->GetOutputPort()); this->TorusActors[axis]->SetMapper(torusMapper); this->TorusActors[axis]->SetProperty(this->Properties[axis]); this->HandlePicker->AddPickList(this->TorusActors[axis]); this->ArrowsActors[axis]->SetMapper(arrowsMapper); this->ArrowsActors[axis]->SetProperty(this->Properties[axis]); this->HandlePicker->AddPickList(this->ArrowsActors[axis]); } this->HandlePicker->SetTolerance(0.001); this->HandlePicker->PickFromListOn(); } //------------------------------------------------------------------------------ vtkOrientationRepresentation::~vtkOrientationRepresentation() = default; //------------------------------------------------------------------------------ void vtkOrientationRepresentation::StartWidgetInteraction(double e[2]) { this->StartEventPosition[0] = e[0]; this->StartEventPosition[1] = e[1]; this->StartEventPosition[2] = 0.0; this->LastEventPosition[0] = e[0]; this->LastEventPosition[1] = e[1]; this->LastEventPosition[2] = 0.0; } //------------------------------------------------------------------------------ void vtkOrientationRepresentation::WidgetInteraction(double e[2]) { // Convert events to appropriate coordinate systems vtkCamera* camera = this->Renderer->GetActiveCamera(); if (!camera) { return; } double vpn[3]; camera->GetViewPlaneNormal(vpn); // Compute the two points defining the motion vector double pos[3]; this->HandlePicker->GetPickPosition(pos); double focalPoint[4], pickPoint[4], prevPickPoint[4]; vtkInteractorObserver::ComputeWorldToDisplay(this->Renderer, pos[0], pos[1], pos[2], focalPoint); double z = focalPoint[2]; vtkInteractorObserver::ComputeDisplayToWorld( this->Renderer, this->LastEventPosition[0], this->LastEventPosition[1], z, prevPickPoint); vtkInteractorObserver::ComputeDisplayToWorld(this->Renderer, e[0], e[1], z, pickPoint); // Process the motion switch (this->InteractionState) { case vtkOrientationRepresentation::RotatingX: this->Rotate(prevPickPoint, pickPoint, ::X_VECTOR); break; case vtkOrientationRepresentation::RotatingY: this->Rotate(prevPickPoint, pickPoint, ::Y_VECTOR); break; case vtkOrientationRepresentation::RotatingZ: this->Rotate(prevPickPoint, pickPoint, ::Z_VECTOR); break; case vtkOrientationRepresentation::Outside: default: break; } this->LastEventPosition[0] = e[0]; this->LastEventPosition[1] = e[1]; this->LastEventPosition[2] = 0.0; } //------------------------------------------------------------------------------ void vtkOrientationRepresentation::Rotate( const double p1[4], const double p2[4], const double baseVector[3]) { double* position = this->BaseTransform->GetPosition(); const double centeredP1[3] = { p1[0] - position[0], p1[1] - position[1], p1[2] - position[2] }; const double centeredP2[3] = { p2[0] - position[0], p2[1] - position[1], p2[2] - position[2] }; double* rotationAxis = this->OrientationTransform->TransformDoubleVector(baseVector); double rotationAngle = vtkMath::SignedAngleBetweenVectors(centeredP1, centeredP2, rotationAxis); this->OrientationTransform->RotateWXYZ(vtkMath::DegreesFromRadians(rotationAngle), rotationAxis); } //------------------------------------------------------------------------------ void vtkOrientationRepresentation::CreateDefaultProperties() { this->Properties[Axis::X_AXIS] = vtkSmartPointer::New(); this->Properties[Axis::Y_AXIS] = vtkSmartPointer::New(); this->Properties[Axis::Z_AXIS] = vtkSmartPointer::New(); this->SelectedProperties[Axis::X_AXIS] = vtkSmartPointer::New(); this->SelectedProperties[Axis::Y_AXIS] = vtkSmartPointer::New(); this->SelectedProperties[Axis::Z_AXIS] = vtkSmartPointer::New(); this->Properties[Axis::X_AXIS]->SetColor(1.0, 0.0, 0.0); this->Properties[Axis::Y_AXIS]->SetColor(0.0, 1.0, 0.0); this->Properties[Axis::Z_AXIS]->SetColor(0.0, 0.0, 1.0); this->SelectedProperties[Axis::X_AXIS]->SetColor(1.0, 0.0, 0.0); this->SelectedProperties[Axis::Y_AXIS]->SetColor(0.0, 1.0, 0.0); this->SelectedProperties[Axis::Z_AXIS]->SetColor(0.0, 0.0, 1.0); this->SelectedProperties[Axis::X_AXIS]->SetAmbient(1.0); this->SelectedProperties[Axis::Y_AXIS]->SetAmbient(1.0); this->SelectedProperties[Axis::Z_AXIS]->SetAmbient(1.0); } //------------------------------------------------------------------------------ void vtkOrientationRepresentation::PlaceWidget(double bds[6]) { double center[3]; this->AdjustBounds(bds, this->InitialBounds, center); this->InitialLength = sqrt((this->InitialBounds[1] - this->InitialBounds[0]) * (this->InitialBounds[1] - this->InitialBounds[0]) + (this->InitialBounds[3] - this->InitialBounds[2]) * (this->InitialBounds[3] - this->InitialBounds[2]) + (this->InitialBounds[5] - this->InitialBounds[4]) * (this->InitialBounds[5] - this->InitialBounds[4])); this->BaseTransform->Identity(); this->BaseTransform->Scale(this->InitialLength, this->InitialLength, this->InitialLength); this->BaseTransform->Translate(center); this->OrientationTransform->Identity(); } //------------------------------------------------------------------------------ int vtkOrientationRepresentation::ComputeInteractionState(int X, int Y, int vtkNotUsed(modify)) { if (!this->Renderer || !this->Renderer->IsInViewport(X, Y)) { return this->InteractionState = vtkOrientationRepresentation::Outside; } this->LastHandle = this->CurrentHandle; this->CurrentHandle = nullptr; vtkAssemblyPath* path = this->GetAssemblyPath(X, Y, 0., this->HandlePicker); if (path) { this->ValidPick = 1; this->CurrentHandle = path->GetFirstNode()->GetViewProp(); } if (!this->CurrentHandle) { return this->InteractionState = vtkOrientationRepresentation::Outside; } if (this->CurrentHandle.Get() == this->TorusActors[Axis::X_AXIS] || this->CurrentHandle.Get() == this->ArrowsActors[Axis::X_AXIS]) { return this->InteractionState = vtkOrientationRepresentation::RotatingX; } else if (this->CurrentHandle.Get() == this->TorusActors[Axis::Y_AXIS] || this->CurrentHandle.Get() == this->ArrowsActors[Axis::Y_AXIS]) { return this->InteractionState = vtkOrientationRepresentation::RotatingY; } else if (this->CurrentHandle.Get() == this->TorusActors[Axis::Z_AXIS] || this->CurrentHandle.Get() == this->ArrowsActors[Axis::Z_AXIS]) { return this->InteractionState = vtkOrientationRepresentation::RotatingZ; } return this->InteractionState = vtkOrientationRepresentation::Outside; } //------------------------------------------------------------------------------ void vtkOrientationRepresentation::SetInteractionState(int state) { // Clamp to allowable values state = std::clamp( state, vtkOrientationRepresentation::Outside, vtkOrientationRepresentation::RotatingZ); this->InteractionState = state; this->HighlightHandle(); } //------------------------------------------------------------------------------ double* vtkOrientationRepresentation::GetBounds() { this->BuildRepresentation(); this->BoundingBox->SetBounds(this->TorusActors[Axis::X_AXIS]->GetBounds()); this->BoundingBox->AddBounds(this->TorusActors[Axis::Y_AXIS]->GetBounds()); this->BoundingBox->AddBounds(this->TorusActors[Axis::Z_AXIS]->GetBounds()); if (this->ShowArrows) { this->BoundingBox->AddBounds(this->ArrowsActors[Axis::X_AXIS]->GetBounds()); this->BoundingBox->AddBounds(this->ArrowsActors[Axis::Y_AXIS]->GetBounds()); this->BoundingBox->AddBounds(this->ArrowsActors[Axis::Z_AXIS]->GetBounds()); } return this->BoundingBox->GetBounds(); } //------------------------------------------------------------------------------ vtkTransform* vtkOrientationRepresentation::GetTransform() { return this->OrientationTransform.Get(); } //------------------------------------------------------------------------------ void vtkOrientationRepresentation::SetOrientation(double values[3]) { double* orientation = this->OrientationTransform->GetOrientation(); if (orientation[0] == values[0] && orientation[1] == values[1] && orientation[2] == values[2]) { return; } this->OrientationTransform->Identity(); this->OrientationTransform->RotateX(values[0]); this->OrientationTransform->RotateY(values[1]); this->OrientationTransform->RotateZ(values[2]); this->Modified(); } //------------------------------------------------------------------------------ void vtkOrientationRepresentation::SetOrientationX(double value) { double* orientation = this->OrientationTransform->GetOrientation(); orientation[0] = value; this->SetOrientation(orientation); } //------------------------------------------------------------------------------ void vtkOrientationRepresentation::SetOrientationY(double value) { double* orientation = this->OrientationTransform->GetOrientation(); orientation[1] = value; this->SetOrientation(orientation); } //------------------------------------------------------------------------------ void vtkOrientationRepresentation::SetOrientationZ(double value) { double* orientation = this->OrientationTransform->GetOrientation(); orientation[2] = value; this->SetOrientation(orientation); } //------------------------------------------------------------------------------ double* vtkOrientationRepresentation::GetOrientation() { return this->OrientationTransform->GetOrientation(); } //------------------------------------------------------------------------------ double vtkOrientationRepresentation::GetOrientationX() { return this->GetOrientation()[0]; } //------------------------------------------------------------------------------ double vtkOrientationRepresentation::GetOrientationY() { return this->GetOrientation()[1]; } //------------------------------------------------------------------------------ double vtkOrientationRepresentation::GetOrientationZ() { return this->GetOrientation()[2]; } //------------------------------------------------------------------------------ void vtkOrientationRepresentation::SetProperty(int axis, bool selected, vtkProperty* property) { Axis clampedAxis = static_cast(std::clamp(axis, Axis::X_AXIS, Axis::Z_AXIS)); if (selected) { if (this->SelectedProperties[clampedAxis] != property) { this->SelectedProperties[clampedAxis] = property; this->Modified(); } } else if (this->Properties[clampedAxis] != property) { // Overwrite actors current property to avoid having to // highlight them for the property to update this->TorusActors[clampedAxis]->SetProperty(property); this->ArrowsActors[clampedAxis]->SetProperty(property); this->Properties[clampedAxis] = property; this->Modified(); } } //------------------------------------------------------------------------------ vtkProperty* vtkOrientationRepresentation::GetProperty(int axis, bool selected) { Axis clampedAxis = static_cast(std::clamp(axis, Axis::X_AXIS, Axis::Z_AXIS)); return selected ? this->SelectedProperties[clampedAxis] : this->Properties[clampedAxis]; } //------------------------------------------------------------------------------ void vtkOrientationRepresentation::BuildRepresentation() { // Rebuild only if necessary if (this->GetMTime() > this->BuildTime) { this->UpdateGeometry(); this->BuildTime.Modified(); } } //------------------------------------------------------------------------------ void vtkOrientationRepresentation::ReleaseGraphicsResources(vtkWindow* w) { for (const auto& torusActor : this->TorusActors) { torusActor.second->ReleaseGraphicsResources(w); } for (const auto& arrowsActor : this->ArrowsActors) { arrowsActor.second->ReleaseGraphicsResources(w); } } //------------------------------------------------------------------------------ int vtkOrientationRepresentation::RenderOpaqueGeometry(vtkViewport* v) { this->BuildRepresentation(); int count = 0; for (const auto& torusActor : this->TorusActors) { count += torusActor.second->RenderOpaqueGeometry(v); } if (this->ShowArrows) { for (const auto& arrowsActor : this->ArrowsActors) { count += arrowsActor.second->RenderOpaqueGeometry(v); } } return count; } //------------------------------------------------------------------------------ int vtkOrientationRepresentation::RenderTranslucentPolygonalGeometry(vtkViewport* v) { this->BuildRepresentation(); int count = 0; for (const auto& torusActor : this->TorusActors) { count += torusActor.second->RenderTranslucentPolygonalGeometry(v); } if (this->ShowArrows) { for (const auto& arrowsActor : this->ArrowsActors) { count += arrowsActor.second->RenderTranslucentPolygonalGeometry(v); } } return count; } //------------------------------------------------------------------------------ vtkTypeBool vtkOrientationRepresentation::HasTranslucentPolygonalGeometry() { this->BuildRepresentation(); int result = 0; for (const auto& torusActor : this->TorusActors) { result |= torusActor.second->HasTranslucentPolygonalGeometry(); } if (this->ShowArrows) { for (const auto& arrowsActor : this->ArrowsActors) { result |= arrowsActor.second->HasTranslucentPolygonalGeometry(); } } return result; } //------------------------------------------------------------------------------ void vtkOrientationRepresentation::UpdateGeometry() { for (const auto& torus : this->TorusSources) { torus->SetThickness(this->TorusThickness); torus->SetScale(1.0, 1.0, this->TorusLength); } for (const auto& arrow : this->ArrowSources) { arrow->SetTipLength(this->ArrowTipLength); arrow->SetTipRadius(this->ArrowTipRadius); arrow->SetShaftRadius(this->ArrowShaftRadius); } this->InitTransforms(); } //------------------------------------------------------------------------------ void vtkOrientationRepresentation::HighlightHandle() { if (vtkActor* actor = vtkActor::SafeDownCast(this->LastHandle)) { if (actor == this->TorusActors[Axis::X_AXIS] || actor == this->ArrowsActors[Axis::X_AXIS]) { this->TorusActors[Axis::X_AXIS]->SetProperty(this->Properties[Axis::X_AXIS]); this->ArrowsActors[Axis::X_AXIS]->SetProperty(this->Properties[Axis::X_AXIS]); } else if (actor == this->TorusActors[Axis::Y_AXIS] || actor == this->ArrowsActors[Axis::Y_AXIS]) { this->TorusActors[Axis::Y_AXIS]->SetProperty(this->Properties[Axis::Y_AXIS]); this->ArrowsActors[Axis::Y_AXIS]->SetProperty(this->Properties[Axis::Y_AXIS]); } else if (actor == this->TorusActors[Axis::Z_AXIS] || actor == this->ArrowsActors[Axis::Z_AXIS]) { this->TorusActors[Axis::Z_AXIS]->SetProperty(this->Properties[Axis::Z_AXIS]); this->ArrowsActors[Axis::Z_AXIS]->SetProperty(this->Properties[Axis::Z_AXIS]); } } if (vtkActor* actor = vtkActor::SafeDownCast(this->CurrentHandle)) { if (actor == this->TorusActors[Axis::X_AXIS] || actor == this->ArrowsActors[Axis::X_AXIS]) { this->TorusActors[Axis::X_AXIS]->SetProperty(this->SelectedProperties[Axis::X_AXIS]); this->ArrowsActors[Axis::X_AXIS]->SetProperty(this->SelectedProperties[Axis::X_AXIS]); } else if (actor == this->TorusActors[Axis::Y_AXIS] || actor == this->ArrowsActors[Axis::Y_AXIS]) { this->TorusActors[Axis::Y_AXIS]->SetProperty(this->SelectedProperties[Axis::Y_AXIS]); this->ArrowsActors[Axis::Y_AXIS]->SetProperty(this->SelectedProperties[Axis::Y_AXIS]); } else if (actor == this->TorusActors[Axis::Z_AXIS] || actor == this->ArrowsActors[Axis::Z_AXIS]) { this->TorusActors[Axis::Z_AXIS]->SetProperty(this->SelectedProperties[Axis::Z_AXIS]); this->ArrowsActors[Axis::Z_AXIS]->SetProperty(this->SelectedProperties[Axis::Z_AXIS]); } } } //------------------------------------------------------------------------------ vtkSmartPointer vtkOrientationRepresentation::GetArrowsOutput(int axisIndex) { int arrowIndex = 4 * axisIndex; vtkNew arrowTransform; arrowTransform->Identity(); arrowTransform->RotateX(::ARROW_ROTATION_X[axisIndex][0]); arrowTransform->RotateY(::ARROW_ROTATION_Y[axisIndex][0]); arrowTransform->RotateZ(::ARROW_ROTATION_Z[axisIndex][0]); vtkNew arrowUFTransformFilter; vtkNew arrowUFTransformFilterBase; arrowUFTransformFilterBase->SetTransform(this->ArrowPosTransform); arrowUFTransformFilterBase->SetInputConnection(this->ArrowSources[arrowIndex++]->GetOutputPort()); arrowUFTransformFilter->SetTransform(arrowTransform); arrowUFTransformFilter->SetInputConnection(arrowUFTransformFilterBase->GetOutputPort()); vtkNew arrowUBTransformFilter; vtkNew arrowUBTransformFilterBase; arrowUBTransformFilterBase->SetTransform(this->ArrowPosInvTransform); arrowUBTransformFilterBase->SetInputConnection(this->ArrowSources[arrowIndex++]->GetOutputPort()); arrowUBTransformFilter->SetTransform(arrowTransform); arrowUBTransformFilter->SetInputConnection(arrowUBTransformFilterBase->GetOutputPort()); vtkNew arrowInvTransform; arrowInvTransform->Identity(); arrowInvTransform->RotateX(::ARROW_ROTATION_X[axisIndex][1]); arrowInvTransform->RotateY(::ARROW_ROTATION_Y[axisIndex][1]); arrowInvTransform->RotateZ(::ARROW_ROTATION_Z[axisIndex][1]); vtkNew arrowDFTransformFilter; vtkNew arrowDFTransformFilterBase; arrowDFTransformFilterBase->SetTransform(this->ArrowPosTransform); arrowDFTransformFilterBase->SetInputConnection(this->ArrowSources[arrowIndex++]->GetOutputPort()); arrowDFTransformFilter->SetTransform(arrowInvTransform); arrowDFTransformFilter->SetInputConnection(arrowDFTransformFilterBase->GetOutputPort()); vtkNew arrowDBTransformFilter; vtkNew arrowDBTransformFilterBase; arrowDBTransformFilterBase->SetTransform(this->ArrowPosInvTransform); arrowDBTransformFilterBase->SetInputConnection(this->ArrowSources[arrowIndex++]->GetOutputPort()); arrowDBTransformFilter->SetTransform(arrowInvTransform); arrowDBTransformFilter->SetInputConnection(arrowDBTransformFilterBase->GetOutputPort()); vtkSmartPointer appendArrows = vtkSmartPointer::New(); appendArrows->AddInputConnection(arrowUFTransformFilter->GetOutputPort()); appendArrows->AddInputConnection(arrowUBTransformFilter->GetOutputPort()); appendArrows->AddInputConnection(arrowDFTransformFilter->GetOutputPort()); appendArrows->AddInputConnection(arrowDBTransformFilter->GetOutputPort()); // For a better rendering, generate normals (torus already generates its own) vtkSmartPointer arrowNormals = vtkSmartPointer::New(); arrowNormals->SetInputConnection(appendArrows->GetOutputPort()); return arrowNormals; } //------------------------------------------------------------------------------ void vtkOrientationRepresentation::InitSources() { this->TorusSources.clear(); this->ArrowSources.clear(); this->TorusSources.reserve(::NUMBER_OF_TORUS); this->ArrowSources.reserve(::NUMBER_OF_ARROWS); for (int i = 0; i < ::NUMBER_OF_TORUS; ++i) { vtkSmartPointer torus = vtkSmartPointer::New(); torus->SetToroidal(1); torus->SetAxisOfSymmetry(i); torus->SetThetaResolution(::TORUS_RESOLUTION); torus->SetPhiRoundness(::TORUS_PHI_ROUNDNESS); torus->SetThickness(this->TorusThickness); torus->SetScale(1.0, 1.0, this->TorusLength); torus->SetCenter(::TORUS_CENTERS[i]); this->TorusSources.push_back(torus); } for (int i = 0; i < ::NUMBER_OF_ARROWS; ++i) { vtkSmartPointer arrow = vtkSmartPointer::New(); arrow->SetTipResolution(::ARROW_RESOLUTION); arrow->SetShaftResolution(::ARROW_RESOLUTION); arrow->SetTipLength(this->ArrowTipLength); arrow->SetTipRadius(this->ArrowTipRadius); arrow->SetShaftRadius(this->ArrowShaftRadius); this->ArrowSources.push_back(arrow); } } //------------------------------------------------------------------------------ void vtkOrientationRepresentation::InitTransforms() { this->ArrowPosTransform->Identity(); this->ArrowPosTransform->Translate(0.0, 0.5 + this->ArrowDistance, 0.0); this->ArrowPosTransform->Scale(this->ArrowLength, 1.0, 1.0); this->ArrowPosInvTransform->Identity(); this->ArrowPosInvTransform->Translate(0.0, -0.5 - this->ArrowDistance, 0.0); this->ArrowPosInvTransform->Scale(this->ArrowLength, 1.0, 1.0); } //------------------------------------------------------------------------------ void vtkOrientationRepresentation::RegisterPickers() { vtkPickingManager* pm = this->GetPickingManager(); if (!pm) { return; } pm->AddPicker(this->HandlePicker, this); } //------------------------------------------------------------------------------ void vtkOrientationRepresentation::GetActors(vtkPropCollection* pc) { if (pc != nullptr && this->GetVisibility()) { for (const auto& torusActor : this->TorusActors) { torusActor.second->GetActors(pc); } if (this->ShowArrows) { for (const auto& arrowsActor : this->ArrowsActors) { arrowsActor.second->GetActors(pc); } } } this->Superclass::GetActors(pc); } //------------------------------------------------------------------------------ void vtkOrientationRepresentation::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); os << indent << "Bounding Box: " << "(" << this->BoundingBox[0] << "," << this->BoundingBox[1] << ") " << "(" << this->BoundingBox[2] << "," << this->BoundingBox[3] << ") " << "(" << this->BoundingBox[4] << "," << this->BoundingBox[5] << ")\n"; os << indent << "Initial Bounds: " << "(" << this->InitialBounds[0] << "," << this->InitialBounds[1] << ") " << "(" << this->InitialBounds[2] << "," << this->InitialBounds[3] << ") " << "(" << this->InitialBounds[4] << "," << this->InitialBounds[5] << ")\n"; os << indent << "Initial Length: " << this->InitialLength << std::endl; os << indent << "Torus Thickness: " << this->TorusThickness << std::endl; os << indent << "Torus Length: " << this->TorusLength << std::endl; os << indent << "Show Arrows: " << (this->ShowArrows ? "On" : "Off") << std::endl; if (this->ShowArrows) { os << indent << "Arrow Length: " << this->ArrowLength << std::endl; os << indent << "Arrow Tip Length: " << this->ArrowTipLength << std::endl; os << indent << "Arrow Tip Radius: " << this->ArrowTipRadius << std::endl; os << indent << "Arrow Shaft Radius: " << this->ArrowShaftRadius << std::endl; os << indent << "Arrow Distance: " << this->ArrowDistance << std::endl; } } VTK_ABI_NAMESPACE_END