/*========================================================================= 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 "vtkPointHandleRepresentation3D.h" #include "vtkActor.h" #include "vtkCamera.h" #include "vtkConeSource.h" #include "vtkLineSource.h" #include "vtkSphereSource.h" #include "vtkPolyDataMapper.h" #include "vtkPolyData.h" #include "vtkCallbackCommand.h" #include "vtkBox.h" #include "vtkPolyData.h" #include "vtkProperty.h" #include "vtkRenderWindowInteractor.h" #include "vtkRenderer.h" #include "vtkInteractorObserver.h" #include "vtkMath.h" #include "vtkLine.h" #include "vtkWindow.h" #include "vtkObjectFactory.h" #include "vtkVectorText.h" #include "vtkFollower.h" #include "vtkCellPicker.h" #include "vtkPolyDataMapper.h" #include "vtkVector.h" #include "vtkVectorOperators.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; this->RestrictFlag = RestrictNone; // 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) { 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]) { // Process the motion if ( this->InteractionState == vtkLineRepresentation::OnP1 ) { if (this->RestrictFlag) { double x[3]; this->Point1Representation->GetWorldPosition(x); for (int i = 0; i < 3; ++i) { x[i] = (this->RestrictFlag == (i + 1)) ? x[i] : this->StartP1[i]; } this->Point1Representation->SetWorldPosition(x); } } else if ( this->InteractionState == vtkLineRepresentation::OnP2 ) { if (this->RestrictFlag) { double x[3]; this->Point2Representation->GetWorldPosition(x); for (int i = 0; i < 3; ++i) { x[i] = (this->RestrictFlag == (i + 1)) ? x[i] : this->StartP2[i]; } this->Point2Representation->SetWorldPosition(x); } } else if ( this->InteractionState == vtkLineRepresentation::OnLine ) { double x[3], p1[3], p2[3], delta[3]; // Get the new position this->LineHandleRepresentation->GetWorldPosition(x); // Compute the delta from the previous position delta[0] = x[0] - this->StartLineHandle[0]; delta[1] = x[1] - this->StartLineHandle[1]; delta[2] = x[2] - this->StartLineHandle[2]; for (int i=0; i<3; i++) { double d = (!this->RestrictFlag || (this->RestrictFlag == (i + 1))) ? delta[i] : 0.0; p1[i] = this->StartP1[i] + d; p2[i] = this->StartP2[i] + d; } 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; } //---------------------------------------------------------------------------- int 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 << indent << "Restring flag: "; switch (this->RestrictFlag) { case RestrictNone: os << "RestrictNone"; break; case RestrictToX: os << "RestrictToX"; break; case RestrictToY: os << "RestrictToY"; break; case RestrictToZ: os << "RestrictToZ"; break; default: os << "unexpected value: " << this->RestrictFlag; break; } 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 }