/*========================================================================= Program: Visualization Toolkit Module: vtkLineRepresentation.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 "vtkLineRepresentation.h" #include "vtkActor.h" #include "vtkBox.h" #include "vtkCallbackCommand.h" #include "vtkCamera.h" #include "vtkCellPicker.h" #include "vtkConeSource.h" #include "vtkFollower.h" #include "vtkInteractorObserver.h" #include "vtkLine.h" #include "vtkLineSource.h" #include "vtkMath.h" #include "vtkObjectFactory.h" #include "vtkPointHandleRepresentation3D.h" #include "vtkPolyData.h" #include "vtkPolyDataMapper.h" #include "vtkProperty.h" #include "vtkRenderWindowInteractor.h" #include "vtkRenderer.h" #include "vtkSphereSource.h" #include "vtkVector.h" #include "vtkVectorOperators.h" #include "vtkVectorText.h" #include "vtkWindow.h" vtkStandardNewMacro(vtkLineRepresentation); vtkCxxSetObjectMacro(vtkLineRepresentation, HandleRepresentation, vtkPointHandleRepresentation3D); //------------------------------------------------------------------------------ vtkLineRepresentation::vtkLineRepresentation() { // Handle size is in pixels for this widget this->HandleSize = 5.0; // By default, use one of these handles this->HandleRepresentation = vtkPointHandleRepresentation3D::New(); this->HandleRepresentation->AllOff(); this->HandleRepresentation->SetHotSpotSize(1.0); this->HandleRepresentation->SetPlaceFactor(1.0); this->HandleRepresentation->TranslationModeOn(); this->Point1Representation = nullptr; this->Point2Representation = nullptr; this->LineHandleRepresentation = nullptr; this->InstantiateHandleRepresentation(); // Miscellaneous parameters this->Tolerance = 5; this->Placed = 0; // Represent the line this->LineSource = vtkLineSource::New(); this->LineSource->SetResolution(5); this->LineMapper = vtkPolyDataMapper::New(); this->LineMapper->SetInputConnection(this->LineSource->GetOutputPort()); this->LineActor = vtkActor::New(); this->LineActor->SetMapper(this->LineMapper); this->DirectionalLine = false; // Create the handles this->Handle = new vtkActor*[2]; this->HandleMapper = new vtkPolyDataMapper*[2]; this->HandleGeometry = new vtkPolyDataAlgorithm*[2]; for (int i = 0; i < 2; i++) { vtkSphereSource* sphere = vtkSphereSource::New(); sphere->SetThetaResolution(16); sphere->SetPhiResolution(8); this->HandleGeometry[i] = sphere; 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]); } // Set up the initial properties this->CreateDefaultProperties(); // Pass the initial properties to the actors. this->Handle[0]->SetProperty(this->EndPointProperty); this->Point1Representation->SetProperty(this->EndPointProperty); this->Handle[1]->SetProperty(this->EndPoint2Property); this->Point2Representation->SetProperty(this->EndPoint2Property); this->LineHandleRepresentation->SetProperty(this->EndPointProperty); this->LineActor->SetProperty(this->LineProperty); // 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; this->PlaceFactor = 1.0; // overload parent's value // The distance text annotation this->DistanceAnnotationVisibility = 0; this->Distance = 0.0; this->DistanceAnnotationFormat = new char[8]; snprintf(this->DistanceAnnotationFormat, 8, "%s", "%-#6.3g"); this->TextInput = vtkVectorText::New(); this->TextInput->SetText("0"); this->TextMapper = vtkPolyDataMapper::New(); this->TextMapper->SetInputConnection(this->TextInput->GetOutputPort()); this->TextActor = vtkFollower::New(); this->TextActor->SetMapper(this->TextMapper); this->TextActor->GetProperty()->SetColor(1.0, 0.1, 0.0); // This needs to be initialized before PlaceWidget is called. this->InitializedDisplayPosition = 0; this->ClampToBounds = 0; // The bounding box this->BoundingBox = vtkBox::New(); this->LinePicker = vtkCellPicker::New(); this->LinePicker->SetTolerance(0.005); // need some fluff this->LinePicker->AddPickList(this->LineActor); this->LinePicker->PickFromListOn(); this->RepresentationState = vtkLineRepresentation::Outside; this->AnnotationTextScaleInitialized = false; // Initial creation of the widget, serves to initialize it. // Call PlaceWidget() LAST in the constructor, as this method depends on ivar // values. this->PlaceWidget(bounds); } //------------------------------------------------------------------------------ vtkLineRepresentation::~vtkLineRepresentation() { if (this->HandleRepresentation) { this->HandleRepresentation->Delete(); } if (this->Point1Representation) { this->Point1Representation->Delete(); } if (this->Point2Representation) { this->Point2Representation->Delete(); } if (this->LineHandleRepresentation) { this->LineHandleRepresentation->Delete(); } this->LineActor->Delete(); this->LineMapper->Delete(); this->LineSource->Delete(); for (int i = 0; i < 2; i++) { this->HandleGeometry[i]->Delete(); this->HandleMapper[i]->Delete(); this->Handle[i]->Delete(); } delete[] this->Handle; delete[] this->HandleMapper; delete[] this->HandleGeometry; this->EndPointProperty->Delete(); this->SelectedEndPointProperty->Delete(); this->EndPoint2Property->Delete(); this->SelectedEndPoint2Property->Delete(); this->LineProperty->Delete(); this->SelectedLineProperty->Delete(); this->BoundingBox->Delete(); delete[] this->DistanceAnnotationFormat; this->DistanceAnnotationFormat = nullptr; this->TextInput->Delete(); this->TextMapper->Delete(); this->TextActor->Delete(); this->LinePicker->Delete(); } //------------------------------------------------------------------------------ void vtkLineRepresentation::SetDirectionalLine(bool val) { if (this->DirectionalLine == val) { return; } this->DirectionalLine = val; this->Modified(); if (this->DirectionalLine) { vtkConeSource* cone = vtkConeSource::New(); cone->SetResolution(16); this->HandleGeometry[1]->Delete(); this->HandleGeometry[1] = cone; } else { vtkSphereSource* sphere = vtkSphereSource::New(); sphere->SetThetaResolution(16); sphere->SetPhiResolution(8); this->HandleGeometry[1]->Delete(); this->HandleGeometry[1] = sphere; } this->HandleMapper[1]->SetInputConnection(this->HandleGeometry[1]->GetOutputPort()); } //------------------------------------------------------------------------------ double vtkLineRepresentation::GetDistance() { return this->Distance; } //------------------------------------------------------------------------------ void vtkLineRepresentation::InstantiateHandleRepresentation() { if (!this->Point1Representation) { this->Point1Representation = this->HandleRepresentation->NewInstance(); this->Point1Representation->ShallowCopy(this->HandleRepresentation); } if (!this->Point2Representation) { this->Point2Representation = this->HandleRepresentation->NewInstance(); this->Point2Representation->ShallowCopy(this->HandleRepresentation); } if (!this->LineHandleRepresentation) { this->LineHandleRepresentation = this->HandleRepresentation->NewInstance(); this->LineHandleRepresentation->ShallowCopy(this->HandleRepresentation); } } //------------------------------------------------------------------------------ void vtkLineRepresentation::SetResolution(int r) { this->LineSource->SetResolution(r); } //------------------------------------------------------------------------------ int vtkLineRepresentation::GetResolution() { return this->LineSource->GetResolution(); } //------------------------------------------------------------------------------ void vtkLineRepresentation::GetPolyData(vtkPolyData* pd) { this->LineSource->Update(); pd->ShallowCopy(this->LineSource->GetOutput()); } //-- Set/Get position of the three handles ----------------------------- // Point1 //------------------------------------------------------------------------------ void vtkLineRepresentation::GetPoint1WorldPosition(double pos[3]) { this->Point1Representation->GetWorldPosition(pos); } double* vtkLineRepresentation::GetPoint1WorldPosition() { return this->Point1Representation->GetWorldPosition(); } //------------------------------------------------------------------------------ void vtkLineRepresentation::GetPoint1DisplayPosition(double pos[3]) { this->Point1Representation->GetDisplayPosition(pos); } double* vtkLineRepresentation::GetPoint1DisplayPosition() { return this->Point1Representation->GetDisplayPosition(); } //------------------------------------------------------------------------------ void vtkLineRepresentation::SetPoint1WorldPosition(double x[3]) { this->Point1Representation->SetWorldPosition(x); this->LineSource->SetPoint1(x); // double p[3]; // this->Point1Representation->GetDisplayPosition(p); // this->Point1Representation->SetDisplayPosition(p); } //------------------------------------------------------------------------------ void vtkLineRepresentation::SetPoint1DisplayPosition(double x[3]) { this->Point1Representation->SetDisplayPosition(x); double p[3]; this->Point1Representation->GetWorldPosition(p); this->Point1Representation->SetWorldPosition(p); } // Point2 //------------------------------------------------------------------------------ void vtkLineRepresentation::GetPoint2WorldPosition(double pos[3]) { this->Point2Representation->GetWorldPosition(pos); } double* vtkLineRepresentation::GetPoint2WorldPosition() { return this->Point2Representation->GetWorldPosition(); } //------------------------------------------------------------------------------ void vtkLineRepresentation::GetPoint2DisplayPosition(double pos[3]) { this->Point2Representation->GetDisplayPosition(pos); } double* vtkLineRepresentation::GetPoint2DisplayPosition() { return this->Point2Representation->GetDisplayPosition(); } //------------------------------------------------------------------------------ void vtkLineRepresentation::SetPoint2WorldPosition(double x[3]) { this->Point2Representation->SetWorldPosition(x); this->LineSource->SetPoint2(x); // double p[3]; // this->Point2Representation->GetDisplayPosition(p); // this->Point2Representation->SetDisplayPosition(p); } //------------------------------------------------------------------------------ void vtkLineRepresentation::SetPoint2DisplayPosition(double x[3]) { this->Point2Representation->SetDisplayPosition(x); double p[3]; this->Point2Representation->GetWorldPosition(p); this->Point2Representation->SetWorldPosition(p); } //------------------------------------------------------------------------------ void vtkLineRepresentation::SetRenderer(vtkRenderer* ren) { this->HandleRepresentation->SetRenderer(ren); this->Point1Representation->SetRenderer(ren); this->Point2Representation->SetRenderer(ren); this->LineHandleRepresentation->SetRenderer(ren); this->Superclass::SetRenderer(ren); } //------------------------------------------------------------------------------ void vtkLineRepresentation::StartWidgetInteraction(double e[2]) { // Store the start position this->StartEventPosition[0] = e[0]; this->StartEventPosition[1] = e[1]; this->StartEventPosition[2] = 0.0; // Store the start position this->LastEventPosition[0] = e[0]; this->LastEventPosition[1] = e[1]; this->LastEventPosition[2] = 0.0; // Get the coordinates of the three handles this->Point1Representation->GetWorldPosition(this->StartP1); this->Point2Representation->GetWorldPosition(this->StartP2); this->LineHandleRepresentation->GetWorldPosition(this->StartLineHandle); if (this->InteractionState == vtkLineRepresentation::Scaling) { double dp1[3], dp2[3]; this->Point1Representation->GetDisplayPosition(dp1); this->Point2Representation->GetDisplayPosition(dp2); this->Length = sqrt((dp1[0] - dp2[0]) * (dp1[0] - dp2[0]) + (dp1[1] - dp2[1]) * (dp1[1] - dp2[1])); } } //------------------------------------------------------------------------------ void vtkLineRepresentation::WidgetInteraction(double e[2]) { if (this->InteractionState == vtkLineRepresentation::OnLine) { double x[3], p1[3], p2[3]; // Get the new position this->LineHandleRepresentation->GetWorldPosition(x); // Compute the delta from the previous position p1[0] = this->StartP1[0] + x[0] - this->StartLineHandle[0]; p1[1] = this->StartP1[1] + x[1] - this->StartLineHandle[1]; p1[2] = this->StartP1[2] + x[2] - this->StartLineHandle[2]; p2[0] = this->StartP2[0] + x[0] - this->StartLineHandle[0]; p2[1] = this->StartP2[1] + x[1] - this->StartLineHandle[1]; p2[2] = this->StartP2[2] + x[2] - this->StartLineHandle[2]; this->Point1Representation->SetWorldPosition(p1); this->Point2Representation->SetWorldPosition(p2); } else if (this->InteractionState == vtkLineRepresentation::Scaling) { // scale about the center of the widget double p1[3], p2[3], center[3]; this->Point1Representation->GetWorldPosition(p1); this->Point2Representation->GetWorldPosition(p2); double delta = sqrt((this->StartEventPosition[0] - e[0]) * (this->StartEventPosition[0] - e[0]) + (this->StartEventPosition[1] - e[1]) * (this->StartEventPosition[1] - e[1])); double sf = 1.0; if (this->Length != 0.0) { sf = 1.0 + delta / this->Length; } if ((e[1] - this->LastEventPosition[1]) < 0.0) { sf = 1 / sf; } for (int i = 0; i < 3; i++) { center[i] = (p1[i] + p2[i]) / 2.0; p1[i] = center[i] + (p1[i] - center[i]) * sf; p2[i] = center[i] + (p2[i] - center[i]) * sf; } this->Point1Representation->SetWorldPosition(p1); this->Point2Representation->SetWorldPosition(p2); } else if (this->InteractionState == vtkLineRepresentation::TranslatingP1) { double x[3], p2[3]; // Get the new position this->Point1Representation->GetWorldPosition(x); for (int i = 0; i < 3; i++) { p2[i] = this->StartP2[i] + (x[i] - this->StartP1[i]); } this->Point2Representation->SetWorldPosition(p2); } else if (this->InteractionState == vtkLineRepresentation::TranslatingP2) { double x[3], p1[3]; // Get the new position this->Point2Representation->GetWorldPosition(x); for (int i = 0; i < 3; i++) { p1[i] = this->StartP1[i] + (x[i] - this->StartP2[i]); } this->Point1Representation->SetWorldPosition(p1); } // Store the start position this->LastEventPosition[0] = e[0]; this->LastEventPosition[1] = e[1]; this->LastEventPosition[2] = 0.0; } //------------------------------------------------------------------------------ void vtkLineRepresentation::PlaceWidget(double bds[6]) { int i; double bounds[6], center[3]; double placeFactor = this->PlaceFactor; this->PlaceFactor = 1.0; this->AdjustBounds(bds, bounds, center); this->PlaceFactor = placeFactor; for (i = 0; i < 6; i++) { this->InitialBounds[i] = bounds[i]; } 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])); // When PlaceWidget() is invoked, the widget orientation is preserved, but it // is allowed to translate and scale. This means it is centered in the // bounding box, and the representation scales itself to intersect the sides // of the bounding box. Thus we have to determine where Point1 and Point2 // intersect the bounding box. double p1[3], p2[3], r[3], o[3], t, placedP1[3], placedP2[3]; this->LineSource->GetPoint1(p1); this->LineSource->GetPoint2(p2); // Okay, this looks really weird, we are shooting rays from OUTSIDE // the bounding box back towards it. This is because the IntersectBox() // method computes intersections only if the ray originates outside the // bounding box. r[0] = this->InitialLength * (p1[0] - p2[0]); r[1] = this->InitialLength * (p1[1] - p2[1]); r[2] = this->InitialLength * (p1[2] - p2[2]); o[0] = center[0] - r[0]; o[1] = center[1] - r[1]; o[2] = center[2] - r[2]; vtkBox::IntersectBox(bounds, o, r, placedP1, t); this->SetPoint1WorldPosition(placedP1); r[0] = this->InitialLength * (p2[0] - p1[0]); r[1] = this->InitialLength * (p2[1] - p1[1]); r[2] = this->InitialLength * (p2[2] - p1[2]); o[0] = center[0] - r[0]; o[1] = center[1] - r[1]; o[2] = center[2] - r[2]; vtkBox::IntersectBox(bounds, o, r, placedP2, t); this->SetPoint2WorldPosition(placedP2); // Initialize the center point this->LineHandleRepresentation->SetWorldPosition(center); // Position the handles at the end of the lines this->Placed = 1; this->ValidPick = 1; this->BuildRepresentation(); } //------------------------------------------------------------------------------ int vtkLineRepresentation::ComputeInteractionState(int x, int y, int vtkNotUsed(modify)) { // Check if we are on end points. Use the handles to determine this. int p1State = this->Point1Representation->ComputeInteractionState(x, y, 0); int p2State = this->Point2Representation->ComputeInteractionState(x, y, 0); if (p1State == vtkHandleRepresentation::Nearby) { this->InteractionState = vtkLineRepresentation::OnP1; this->SetRepresentationState(vtkLineRepresentation::OnP1); } else if (p2State == vtkHandleRepresentation::Nearby) { this->InteractionState = vtkLineRepresentation::OnP2; this->SetRepresentationState(vtkLineRepresentation::OnP2); } else { this->InteractionState = vtkLineRepresentation::Outside; } // Okay if we're near a handle return, otherwise test the line if (this->InteractionState != vtkLineRepresentation::Outside) { return this->InteractionState; } // Check if we are on edges double pos1[3], pos2[3]; this->GetPoint1DisplayPosition(pos1); this->GetPoint2DisplayPosition(pos2); double p1[3], p2[3], xyz[3]; double t, closest[3]; xyz[0] = static_cast(x); xyz[1] = static_cast(y); p1[0] = static_cast(pos1[0]); p1[1] = static_cast(pos1[1]); p2[0] = static_cast(pos2[0]); p2[1] = static_cast(pos2[1]); xyz[2] = p1[2] = p2[2] = 0.0; double tol2 = this->Tolerance * this->Tolerance; int onLine = (vtkLine::DistanceToLine(xyz, p1, p2, t, closest) <= tol2); if (onLine && t < 1.0 && t > 0.0) { this->InteractionState = vtkLineRepresentation::OnLine; this->SetRepresentationState(vtkLineRepresentation::OnLine); this->GetPoint1WorldPosition(pos1); this->GetPoint2WorldPosition(pos2); this->LinePicker->Pick(x, y, 0.0, this->Renderer); this->LinePicker->GetPickPosition(closest); this->LineHandleRepresentation->SetWorldPosition(closest); } else { this->InteractionState = vtkLineRepresentation::Outside; this->SetRepresentationState(vtkLineRepresentation::Outside); } return this->InteractionState; } //------------------------------------------------------------------------------ void vtkLineRepresentation::SetRepresentationState(int state) { if (this->RepresentationState == state) { return; } state = (state < vtkLineRepresentation::Outside ? vtkLineRepresentation::Outside : (state > vtkLineRepresentation::Scaling ? vtkLineRepresentation::Scaling : state)); this->RepresentationState = state; this->Modified(); if (state == vtkLineRepresentation::Outside) { this->HighlightPoint(0, 0); this->HighlightPoint(1, 0); this->HighlightLine(0); } else if (state == vtkLineRepresentation::OnP1) { this->HighlightPoint(0, 1); this->HighlightPoint(1, 0); this->HighlightLine(0); } else if (state == vtkLineRepresentation::OnP2) { this->HighlightPoint(0, 0); this->HighlightPoint(1, 1); this->HighlightLine(0); } else if (state == vtkLineRepresentation::OnLine) { this->HighlightPoint(0, 0); this->HighlightPoint(1, 0); this->HighlightLine(1); } else { this->HighlightPoint(0, 1); this->HighlightPoint(1, 1); this->HighlightLine(1); } } //------------------------------------------------------------------------------ double* vtkLineRepresentation::GetBounds() { this->BuildRepresentation(); this->BoundingBox->SetBounds(this->LineActor->GetBounds()); this->BoundingBox->AddBounds(this->Handle[0]->GetBounds()); this->BoundingBox->AddBounds(this->Handle[1]->GetBounds()); return this->BoundingBox->GetBounds(); } //------------------------------------------------------------------------------ void vtkLineRepresentation::CreateDefaultProperties() { // Endpoint properties this->EndPointProperty = vtkProperty::New(); this->EndPointProperty->SetColor(1, 1, 1); this->SelectedEndPointProperty = vtkProperty::New(); this->SelectedEndPointProperty->SetColor(0, 1, 0); this->EndPoint2Property = vtkProperty::New(); this->EndPoint2Property->SetColor(1, 1, 1); this->SelectedEndPoint2Property = vtkProperty::New(); this->SelectedEndPoint2Property->SetColor(0, 1, 0); // Line properties this->LineProperty = vtkProperty::New(); this->LineProperty->SetAmbient(1.0); this->LineProperty->SetAmbientColor(1.0, 1.0, 1.0); this->LineProperty->SetLineWidth(2.0); this->SelectedLineProperty = vtkProperty::New(); this->SelectedLineProperty->SetAmbient(1.0); this->SelectedLineProperty->SetAmbientColor(0.0, 1.0, 0.0); this->SelectedLineProperty->SetLineWidth(2.0); } //------------------------------------------------------------------------------ void vtkLineRepresentation::SizeHandles() { // The SizeHandles() method depends on the LastPickPosition data member. double radius = this->vtkWidgetRepresentation::SizeHandlesInPixels(1.35, this->LineSource->GetPoint1()); static_cast(this->HandleGeometry[0])->SetRadius(radius); radius = this->vtkWidgetRepresentation::SizeHandlesInPixels(1.35, this->LineSource->GetPoint2()); if (this->DirectionalLine) { static_cast(this->HandleGeometry[1])->SetRadius(radius); static_cast(this->HandleGeometry[1])->SetHeight(2.8 * radius); } else { static_cast(this->HandleGeometry[1])->SetRadius(radius); } } //------------------------------------------------------------------------------ void vtkLineRepresentation::BuildRepresentation() { // Rebuild only if necessary if (this->GetMTime() > this->BuildTime || this->Point1Representation->GetMTime() > this->BuildTime || this->Point2Representation->GetMTime() > this->BuildTime || this->LineHandleRepresentation->GetMTime() > this->BuildTime || (this->Renderer && this->Renderer->GetVTKWindow() && (this->Renderer->GetVTKWindow()->GetMTime() > this->BuildTime || this->Renderer->GetActiveCamera()->GetMTime() > this->BuildTime))) { if (!this->InitializedDisplayPosition && this->Renderer) { this->SetPoint1WorldPosition(this->LineSource->GetPoint1()); this->SetPoint2WorldPosition(this->LineSource->GetPoint2()); this->ValidPick = 1; this->InitializedDisplayPosition = 1; } // Make sure that tolerance is consistent between handles and this representation this->Point1Representation->SetTolerance(this->Tolerance); this->Point2Representation->SetTolerance(this->Tolerance); this->LineHandleRepresentation->SetTolerance(this->Tolerance); // Retrieve end point information double x1[3], x2[3]; this->GetPoint1WorldPosition(x1); this->LineSource->SetPoint1(x1); static_cast(this->HandleGeometry[0])->SetCenter(x1); this->GetPoint2WorldPosition(x2); this->LineSource->SetPoint2(x2); if (this->DirectionalLine) { static_cast(this->HandleGeometry[1])->SetCenter(x2); vtkVector3d dir(x2); dir = dir - vtkVector3d(x1); static_cast(this->HandleGeometry[1])->SetDirection(dir.GetData()); } else { static_cast(this->HandleGeometry[1])->SetCenter(x2); } this->Distance = sqrt(vtkMath::Distance2BetweenPoints(x1, x2)); // Place the DistanceAnnotation right in between the two points. double x[3] = { (x1[0] + x2[0]) / 2.0, (x1[1] + x2[1]) / 2.0, (x1[2] + x2[2]) / 2.0 }; char string[512]; snprintf(string, sizeof(string), this->DistanceAnnotationFormat, this->Distance); this->TextInput->SetText(string); this->TextActor->SetPosition(x); if (this->Renderer) { this->TextActor->SetCamera(this->Renderer->GetActiveCamera()); } if (!this->AnnotationTextScaleInitialized) { // If a font size hasn't been specified by the user, scale the text // (font size) according to the length of the line widget. this->TextActor->SetScale( this->Distance / 10.0, this->Distance / 10.0, this->Distance / 10.0); } this->SizeHandles(); this->BuildTime.Modified(); } } //------------------------------------------------------------------------------ void vtkLineRepresentation::HighlightPoint(int ptId, int highlight) { if (ptId == 0) { if (highlight) { this->Handle[0]->SetProperty(this->SelectedEndPointProperty); this->Point1Representation->SetSelectedProperty(this->SelectedEndPointProperty); } else { this->Handle[0]->SetProperty(this->EndPointProperty); this->Point1Representation->SetProperty(this->EndPointProperty); } } else if (ptId == 1) { if (highlight) { this->Handle[1]->SetProperty(this->SelectedEndPoint2Property); this->Point2Representation->SetSelectedProperty(this->SelectedEndPoint2Property); } else { this->Handle[1]->SetProperty(this->EndPoint2Property); this->Point2Representation->SetProperty(this->EndPoint2Property); } } else // if ( ptId == 2 ) { if (highlight) { this->LineHandleRepresentation->SetSelectedProperty(this->SelectedEndPointProperty); } else { this->LineHandleRepresentation->SetProperty(this->EndPointProperty); } } } //------------------------------------------------------------------------------ void vtkLineRepresentation::HighlightLine(int highlight) { if (highlight) { this->LineActor->SetProperty(this->SelectedLineProperty); } else { this->LineActor->SetProperty(this->LineProperty); } } //------------------------------------------------------------------------------ void vtkLineRepresentation::SetLineColor(double r, double g, double b) { if (this->GetLineProperty()) { this->GetLineProperty()->SetColor(r, g, b); } } //------------------------------------------------------------------------------ void vtkLineRepresentation::ClampPosition(double x[3]) { for (int i = 0; i < 3; i++) { if (x[i] < this->InitialBounds[2 * i]) { x[i] = this->InitialBounds[2 * i]; } if (x[i] > this->InitialBounds[2 * i + 1]) { x[i] = this->InitialBounds[2 * i + 1]; } } } //------------------------------------------------------------------------------ int vtkLineRepresentation::InBounds(double x[3]) { for (int i = 0; i < 3; i++) { if (x[i] < this->InitialBounds[2 * i] || x[i] > this->InitialBounds[2 * i + 1]) { return 0; } } return 1; } //------------------------------------------------------------------------------ void vtkLineRepresentation::GetActors(vtkPropCollection* pc) { this->LineActor->GetActors(pc); this->Handle[0]->GetActors(pc); this->Handle[1]->GetActors(pc); this->TextActor->GetActors(pc); } //------------------------------------------------------------------------------ void vtkLineRepresentation::ReleaseGraphicsResources(vtkWindow* w) { this->LineActor->ReleaseGraphicsResources(w); this->Handle[0]->ReleaseGraphicsResources(w); this->Handle[1]->ReleaseGraphicsResources(w); this->TextActor->ReleaseGraphicsResources(w); } //------------------------------------------------------------------------------ int vtkLineRepresentation::RenderOpaqueGeometry(vtkViewport* v) { int count = 0; this->BuildRepresentation(); count += this->LineActor->RenderOpaqueGeometry(v); count += this->Handle[0]->RenderOpaqueGeometry(v); count += this->Handle[1]->RenderOpaqueGeometry(v); if (this->DistanceAnnotationVisibility) { count += this->TextActor->RenderOpaqueGeometry(v); } return count; } //------------------------------------------------------------------------------ int vtkLineRepresentation::RenderTranslucentPolygonalGeometry(vtkViewport* v) { int count = 0; this->BuildRepresentation(); count += this->LineActor->RenderTranslucentPolygonalGeometry(v); count += this->Handle[0]->RenderTranslucentPolygonalGeometry(v); count += this->Handle[1]->RenderTranslucentPolygonalGeometry(v); if (this->DistanceAnnotationVisibility) { count += this->TextActor->RenderTranslucentPolygonalGeometry(v); } return count; } //------------------------------------------------------------------------------ vtkTypeBool vtkLineRepresentation::HasTranslucentPolygonalGeometry() { int result = 0; this->BuildRepresentation(); result |= this->LineActor->HasTranslucentPolygonalGeometry(); result |= this->Handle[0]->HasTranslucentPolygonalGeometry(); result |= this->Handle[1]->HasTranslucentPolygonalGeometry(); if (this->DistanceAnnotationVisibility) { result |= this->TextActor->HasTranslucentPolygonalGeometry(); } return result; } //------------------------------------------------------------------------------ vtkMTimeType vtkLineRepresentation::GetMTime() { vtkMTimeType mTime = this->Superclass::GetMTime(); vtkMTimeType mTime2 = this->Point1Representation->GetMTime(); mTime = (mTime2 > mTime ? mTime2 : mTime); mTime2 = this->Point2Representation->GetMTime(); mTime = (mTime2 > mTime ? mTime2 : mTime); mTime2 = this->LineHandleRepresentation->GetMTime(); mTime = (mTime2 > mTime ? mTime2 : mTime); return mTime; } //------------------------------------------------------------------------------ void vtkLineRepresentation::SetDistanceAnnotationScale(double scale[3]) { this->TextActor->SetScale(scale); this->AnnotationTextScaleInitialized = true; } //------------------------------------------------------------------------------ double* vtkLineRepresentation::GetDistanceAnnotationScale() { return this->TextActor->GetScale(); } //------------------------------------------------------------------------------ vtkProperty* vtkLineRepresentation::GetDistanceAnnotationProperty() { return this->TextActor->GetProperty(); } //------------------------------------------------------------------------------ void vtkLineRepresentation::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); if (this->LineProperty) { os << indent << "Line Property: " << this->LineProperty << "\n"; } else { os << indent << "Line Property: (none)\n"; } if (this->SelectedLineProperty) { os << indent << "Selected Line Property: " << this->SelectedLineProperty << "\n"; } else { os << indent << "Selected Line Property: (none)\n"; } if (this->EndPointProperty) { os << indent << "End Point Property: " << this->EndPointProperty << "\n"; } else { os << indent << "End Point Property: (none)\n"; } if (this->SelectedEndPointProperty) { os << indent << "Selected End Point Property: " << this->SelectedEndPointProperty << "\n"; } else { os << indent << "Selected End Point Property: (none)\n"; } if (this->EndPoint2Property) { os << indent << "End Point Property: " << this->EndPoint2Property << "\n"; } else { os << indent << "End Point Property: (none)\n"; } if (this->SelectedEndPoint2Property) { os << indent << "Selected End Point Property: " << this->SelectedEndPoint2Property << "\n"; } else { os << indent << "Selected End Point Property: (none)\n"; } os << indent << "Tolerance: " << this->Tolerance << "\n"; os << indent << "Constrain To Bounds: " << (this->ClampToBounds ? "On\n" : "Off\n"); int res = this->LineSource->GetResolution(); double* pt1 = this->LineSource->GetPoint1(); double* pt2 = this->LineSource->GetPoint2(); os << indent << "Resolution: " << res << "\n"; os << indent << "Point 1: (" << pt1[0] << ", " << pt1[1] << ", " << pt1[2] << ")\n"; os << indent << "Point 2: (" << pt2[0] << ", " << pt2[1] << ", " << pt2[2] << ")\n"; os << indent << "Point1 Representation: "; this->Point1Representation->PrintSelf(os, indent.GetNextIndent()); os << indent << "Point2 Representation: "; this->Point2Representation->PrintSelf(os, indent.GetNextIndent()); os << indent << "Line Handle Representation: "; this->LineHandleRepresentation->PrintSelf(os, indent.GetNextIndent()); os << indent << "Representation State: " << this->RepresentationState << "\n"; os << indent << "Directional Line: " << this->DirectionalLine << "\n"; os << "\n"; os << indent << "DistanceAnnotationVisibility: "; if (this->DistanceAnnotationVisibility) { os << this->DistanceAnnotationVisibility << "\n"; } else { os << "(none)\n"; } os << indent << "DistanceAnnotationFormat: "; if (this->DistanceAnnotationFormat) { os << this->DistanceAnnotationFormat << "\n"; } else { os << "(none)\n"; } os << indent << "TextActor: "; if (this->TextActor) { os << this->TextActor << "\n"; } else { os << "(none)\n"; } // this->InteractionState is printed in superclass // this is commented to avoid PrintSelf errors }