/*========================================================================= Program: Visualization Toolkit Module: vtkBiDimensionalRepresentation2D.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 "vtkBiDimensionalRepresentation2D.h" #include "vtkActor2D.h" #include "vtkCellArray.h" #include "vtkCoordinate.h" #include "vtkHandleRepresentation.h" #include "vtkInteractorObserver.h" #include "vtkLine.h" #include "vtkMath.h" #include "vtkObjectFactory.h" #include "vtkPointHandleRepresentation2D.h" #include "vtkPoints.h" #include "vtkPolyData.h" #include "vtkPolyDataMapper2D.h" #include "vtkProperty2D.h" #include "vtkRenderer.h" #include "vtkTextMapper.h" #include "vtkTextProperty.h" #include "vtkWindow.h" #include vtkStandardNewMacro(vtkBiDimensionalRepresentation2D); //------------------------------------------------------------------------------ vtkBiDimensionalRepresentation2D::vtkBiDimensionalRepresentation2D() { // Create the geometry for the two axes this->LineCells = vtkCellArray::New(); this->LineCells->InsertNextCell(2); this->LineCells->InsertCellPoint(0); this->LineCells->InsertCellPoint(1); this->LineCells->InsertNextCell(2); this->LineCells->InsertCellPoint(2); this->LineCells->InsertCellPoint(3); this->LinePoints = vtkPoints::New(); this->LinePoints->SetNumberOfPoints(4); this->LinePolyData = vtkPolyData::New(); this->LinePolyData->SetPoints(this->LinePoints); this->LinePolyData->SetLines(this->LineCells); this->LineMapper = vtkPolyDataMapper2D::New(); this->LineMapper->SetInputData(this->LinePolyData); this->LineProperty = vtkProperty2D::New(); this->LineActor = vtkActor2D::New(); this->LineActor->SetProperty(this->LineProperty); this->LineActor->SetMapper(this->LineMapper); this->SelectedLineProperty = vtkProperty2D::New(); this->SelectedLineProperty->SetColor(0.0, 1.0, 0.0); this->SelectedLineProperty->SetLineWidth(2.0); this->TextProperty = vtkTextProperty::New(); this->TextProperty->SetBold(1); this->TextProperty->SetItalic(1); this->TextProperty->SetShadow(1); this->TextProperty->SetFontFamilyToArial(); this->TextMapper = vtkTextMapper::New(); this->TextMapper->SetTextProperty(this->TextProperty); this->TextMapper->SetInput("0.0"); this->TextActor = vtkActor2D::New(); this->TextActor->SetMapper(this->TextMapper); } //------------------------------------------------------------------------------ vtkBiDimensionalRepresentation2D::~vtkBiDimensionalRepresentation2D() { this->LineCells->Delete(); this->LinePoints->Delete(); this->LinePolyData->Delete(); this->LineMapper->Delete(); this->LineProperty->Delete(); this->LineActor->Delete(); this->SelectedLineProperty->Delete(); this->TextProperty->Delete(); this->TextMapper->Delete(); this->TextActor->Delete(); } //------------------------------------------------------------------------------ int vtkBiDimensionalRepresentation2D::ComputeInteractionState(int X, int Y, int modify) { this->Modifier = modify; // Check if we are on end points. The handles must tell us to ensure // consistent state. int p1State = this->Point1Representation->ComputeInteractionState(X, Y, 0); int p2State = this->Point2Representation->ComputeInteractionState(X, Y, 0); int p3State = this->Point3Representation->ComputeInteractionState(X, Y, 0); int p4State = this->Point4Representation->ComputeInteractionState(X, Y, 0); if (p1State == vtkHandleRepresentation::Nearby) { this->InteractionState = vtkBiDimensionalRepresentation2D::NearP1; } else if (p2State == vtkHandleRepresentation::Nearby) { this->InteractionState = vtkBiDimensionalRepresentation2D::NearP2; } else if (p3State == vtkHandleRepresentation::Nearby) { this->InteractionState = vtkBiDimensionalRepresentation2D::NearP3; } else if (p4State == vtkHandleRepresentation::Nearby) { this->InteractionState = vtkBiDimensionalRepresentation2D::NearP4; } else { this->InteractionState = vtkBiDimensionalRepresentation2D::Outside; } // Okay if we're near a handle return, otherwise test edges. if (this->InteractionState != vtkBiDimensionalRepresentation2D::Outside) { return this->InteractionState; } // See if we are near the edges. Requires separate computation. double pos1[3], pos2[3], pos3[3], pos4[3]; this->GetPoint1DisplayPosition(pos1); this->GetPoint2DisplayPosition(pos2); this->GetPoint3DisplayPosition(pos3); this->GetPoint4DisplayPosition(pos4); double p1[3], p2[3], p3[3], p4[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]); p3[0] = static_cast(pos3[0]); p3[1] = static_cast(pos3[1]); p4[0] = static_cast(pos4[0]); p4[1] = static_cast(pos4[1]); xyz[2] = p1[2] = p2[2] = p3[2] = p4[2] = 0.0; double tol2 = this->Tolerance * this->Tolerance; // Compute intersection point. double uIntersect, vIntersect; vtkLine::Intersection(p1, p2, p3, p4, uIntersect, vIntersect); // Check if we are on edges int onL1 = (vtkLine::DistanceToLine(xyz, p1, p2, t, closest) <= tol2); int onL2 = (vtkLine::DistanceToLine(xyz, p3, p4, t, closest) <= tol2); double xyzParam; if (onL1 && onL2) { this->InteractionState = vtkBiDimensionalRepresentation2D::OnCenter; } else if (onL1) { if (p1[0] != p2[0]) { xyzParam = (xyz[0] - p1[0]) / (p2[0] - p1[0]); if (xyzParam < uIntersect) { // closer to p1 if (xyzParam < (uIntersect * 0.5)) { this->InteractionState = vtkBiDimensionalRepresentation2D::OnL1Outer; } else { this->InteractionState = vtkBiDimensionalRepresentation2D::OnL1Inner; } } else { // closer to p2 if (xyzParam > ((1 + uIntersect) * 0.5)) { this->InteractionState = vtkBiDimensionalRepresentation2D::OnL1Outer; } else { this->InteractionState = vtkBiDimensionalRepresentation2D::OnL1Inner; } } } else { xyzParam = (xyz[1] - p1[1]) / (p2[1] - p1[1]); if (xyzParam < uIntersect) { // closer to p1 if (xyzParam < (uIntersect * 0.5)) { this->InteractionState = vtkBiDimensionalRepresentation2D::OnL1Outer; } else { this->InteractionState = vtkBiDimensionalRepresentation2D::OnL1Inner; } } else { // closer to p2 if (xyzParam > ((1 + uIntersect) * 0.5)) { this->InteractionState = vtkBiDimensionalRepresentation2D::OnL1Outer; } else { this->InteractionState = vtkBiDimensionalRepresentation2D::OnL1Inner; } } } } else if (onL2) { if (p3[0] != p4[0]) { xyzParam = (xyz[0] - p3[0]) / (p4[0] - p3[0]); if (xyzParam < vIntersect) { // closer to p3 if (xyzParam < (vIntersect * 0.5)) { this->InteractionState = vtkBiDimensionalRepresentation2D::OnL2Outer; } else { this->InteractionState = vtkBiDimensionalRepresentation2D::OnL2Inner; } } else { // closer to p4 if (xyzParam > ((1 + vIntersect) * 0.5)) { this->InteractionState = vtkBiDimensionalRepresentation2D::OnL2Outer; } else { this->InteractionState = vtkBiDimensionalRepresentation2D::OnL2Inner; } } } else { xyzParam = (xyz[1] - p3[1]) / (p4[1] - p3[1]); if (xyzParam < vIntersect) { // closer to p3 if (xyzParam < (vIntersect * 0.5)) { this->InteractionState = vtkBiDimensionalRepresentation2D::OnL2Outer; } else { this->InteractionState = vtkBiDimensionalRepresentation2D::OnL2Inner; } } else { // closer to p4 if (xyzParam > ((1 + vIntersect) * 0.5)) { this->InteractionState = vtkBiDimensionalRepresentation2D::OnL2Outer; } else { this->InteractionState = vtkBiDimensionalRepresentation2D::OnL2Inner; } } } } else { this->InteractionState = vtkBiDimensionalRepresentation2D::Outside; this->Modifier = 0; } return this->InteractionState; } //------------------------------------------------------------------------------ void vtkBiDimensionalRepresentation2D::StartWidgetDefinition(double e[2]) { double pos[3]; pos[0] = e[0]; pos[1] = e[1]; pos[2] = 0.0; this->SetPoint1DisplayPosition(pos); this->SetPoint2DisplayPosition(pos); this->SetPoint3DisplayPosition(pos); this->SetPoint4DisplayPosition(pos); this->StartEventPosition[0] = pos[0]; this->StartEventPosition[1] = pos[1]; this->StartEventPosition[2] = pos[2]; } //------------------------------------------------------------------------------ void vtkBiDimensionalRepresentation2D::Point2WidgetInteraction(double e[2]) { double pos[3], p1[3]; pos[0] = e[0]; pos[1] = e[1]; pos[2] = 0.0; // Make sure that the two points are not coincident this->GetPoint1DisplayPosition(p1); if (((pos[0] - p1[0]) * (pos[0] - p1[0]) + (pos[1] - p1[1]) * (pos[1] - p1[1])) < 2) { pos[0] += 2; } this->SetPoint2DisplayPosition(pos); } //------------------------------------------------------------------------------ // This method is called when Point3 is to be manipulated. Note that Point3 // and Point4 are constrained relative to Line1. As a result, manipulating P3 // results in manipulating P4. void vtkBiDimensionalRepresentation2D::Point3WidgetInteraction(double e[2]) { double p1[3], p2[3], p3[3], p4[3]; double slope1[3], slope2[3]; // Start by getting the coordinates (P1,P2) defining Line1. Also get // characteristics of Line1 including its slope, etc. this->GetPoint1WorldPosition(p1); this->GetPoint2WorldPosition(p2); slope1[0] = p2[0] - p1[0]; slope1[1] = p2[1] - p1[1]; slope2[0] = -slope1[1]; slope2[1] = slope1[0]; slope2[2] = 0.0; vtkMath::Normalize(slope2); // The current position of P3 is constrained to lie along Line1. Also, // P4 is placed on the opposite side of Line1. double pw[4], t, closest[3]; if (this->Renderer) { this->Renderer->SetDisplayPoint(e[0], e[1], 0.0); this->Renderer->DisplayToWorld(); this->Renderer->GetWorldPoint(pw); } double dist = sqrt(vtkLine::DistanceToLine(pw, p1, p2, t, closest)); // Set the positions of P3 and P4. p3[0] = closest[0] + dist * slope2[0]; p3[1] = closest[1] + dist * slope2[1]; p3[2] = pw[2]; this->SetPoint3WorldPosition(p3); p4[0] = closest[0] - dist * slope2[0]; p4[1] = closest[1] - dist * slope2[1]; p4[2] = pw[2]; this->SetPoint4WorldPosition(p4); } //------------------------------------------------------------------------------ void vtkBiDimensionalRepresentation2D::StartWidgetManipulation(double e[2]) { this->StartEventPosition[0] = e[0]; this->StartEventPosition[1] = e[1]; this->StartEventPosition[2] = 0.0; if (this->Renderer) { this->Renderer->SetDisplayPoint(e[0], e[1], 0.0); this->Renderer->DisplayToWorld(); this->Renderer->GetWorldPoint(this->StartEventPositionWorld); } this->GetPoint1WorldPosition(this->P1World); this->GetPoint2WorldPosition(this->P2World); this->GetPoint3WorldPosition(this->P3World); this->GetPoint4WorldPosition(this->P4World); int i; for (i = 0; i < 3; i++) { this->P21World[i] = this->P2World[i] - this->P1World[i]; this->P43World[i] = this->P4World[i] - this->P3World[i]; } vtkLine::Intersection( this->P1World, this->P2World, this->P3World, this->P4World, this->T21, this->T43); // Compute the center point for (i = 0; i < 3; i++) { this->CenterWorld[i] = ((this->P1World[i] + this->T21 * this->P21World[i]) + (this->P3World[i] + this->T43 * this->P43World[i])) / 2.0; } } //------------------------------------------------------------------------------ // This handles all the nasty special cases when the length of the arms of the // bidimensional widget become zero. Basically the method prevents the arms // from getting too short. void vtkBiDimensionalRepresentation2D::ProjectOrthogonalPoint( double x[4], double y[3], double x1[3], double x2[3], double x21[3], double dir, double xP[3]) { double t, closest[3], slope[3], dist; // determine the distance from the other (orthogonal) line dist = dir * sqrt(vtkLine::DistanceToLine(x, x1, x2, t, closest)); // get the closest point on the other line, use its "mate" point to define the projection point, // this keeps everything orthogonal. vtkLine::DistanceToLine(y, x1, x2, t, closest); // Project the point "dist" orthogonal to ray x21. // Define an orthogonal line. slope[0] = -x21[1]; slope[1] = x21[0]; slope[2] = 0.0; // Project out the right distance along the calculated slope vtkMath::Normalize(slope); xP[0] = closest[0] + dist * slope[0]; xP[1] = closest[1] + dist * slope[1]; xP[2] = closest[2] + dist * slope[2]; // Check to see what side the projection is on, clamp if necessary. Note that closest is modified // so that the arms don't end up with zero length. if (((xP[0] - closest[0]) * (x[0] - closest[0]) + (xP[1] - closest[1]) * (x[1] - closest[1]) + (xP[2] - closest[2]) * (x[2] - closest[2])) < 0.0) { // Convert closest point to display coordinates double c1[3], c2[3], c21[3], cNew[3], xPNew[4]; this->Renderer->SetWorldPoint(closest[0], closest[1], closest[2], 1.0); this->Renderer->WorldToDisplay(); this->Renderer->GetDisplayPoint(c1); // Convert vector in world space to display space this->Renderer->SetWorldPoint( closest[0] + dir * slope[0], closest[1] + dir * slope[1], closest[2] + dir * slope[2], 1.0); this->Renderer->WorldToDisplay(); this->Renderer->GetDisplayPoint(c2); c21[0] = c2[0] - c1[0]; c21[1] = c2[1] - c1[1]; c21[2] = c2[2] - c1[2]; vtkMath::Normalize(c21); // Perform vector addition in display space to get new point cNew[0] = c1[0] + c21[0]; cNew[1] = c1[1] + c21[1]; cNew[2] = c1[2] + c21[2]; this->Renderer->SetDisplayPoint(cNew[0], cNew[1], cNew[2]); this->Renderer->DisplayToWorld(); this->Renderer->GetWorldPoint(xPNew); xP[0] = xPNew[0]; xP[1] = xPNew[1]; xP[2] = xPNew[2]; } } //------------------------------------------------------------------------------ // This method is tricky because it is constrained by Line1 and Line2. // This method is invoked after all four points have been placed. void vtkBiDimensionalRepresentation2D::WidgetInteraction(double e[2]) { // Depending on the state, different motions are allowed. if (this->InteractionState == Outside || !this->Renderer) { return; } // Okay, go to work, convert this event to world coordinates double pw[4], t, closest[3]; double p1[3], p2[3], p3[3], p4[3]; this->Renderer->SetDisplayPoint(e[0], e[1], 0.0); this->Renderer->DisplayToWorld(); this->Renderer->GetWorldPoint(pw); // depending on the state, perform different operations if (this->InteractionState == OnCenter) { for (int i = 0; i < 3; i++) { p1[i] = this->P1World[i] + (pw[i] - this->StartEventPositionWorld[i]); p2[i] = this->P2World[i] + (pw[i] - this->StartEventPositionWorld[i]); p3[i] = this->P3World[i] + (pw[i] - this->StartEventPositionWorld[i]); p4[i] = this->P4World[i] + (pw[i] - this->StartEventPositionWorld[i]); } this->SetPoint1WorldPosition(p1); this->SetPoint2WorldPosition(p2); this->SetPoint3WorldPosition(p3); this->SetPoint4WorldPosition(p4); } else if (this->InteractionState == OnL1Outer || this->InteractionState == OnL2Outer) // rotate the representation { // compute rotation angle and center of rotation double sc[3], ec[3], p1c[3], p2c[3], p3c[3], p4c[3]; for (int i = 0; i < 3; i++) { sc[i] = this->StartEventPositionWorld[i] - this->CenterWorld[i]; ec[i] = pw[i] - this->CenterWorld[i]; p1c[i] = this->P1World[i] - this->CenterWorld[i]; p2c[i] = this->P2World[i] - this->CenterWorld[i]; p3c[i] = this->P3World[i] - this->CenterWorld[i]; p4c[i] = this->P4World[i] - this->CenterWorld[i]; } double theta = atan2(ec[1], ec[0]) - atan2(sc[1], sc[0]); double r1 = vtkMath::Norm(p1c); double r2 = vtkMath::Norm(p2c); double r3 = vtkMath::Norm(p3c); double r4 = vtkMath::Norm(p4c); double theta1 = atan2(p1c[1], p1c[0]); double theta2 = atan2(p2c[1], p2c[0]); double theta3 = atan2(p3c[1], p3c[0]); double theta4 = atan2(p4c[1], p4c[0]); // rotate the four points p1[0] = this->CenterWorld[0] + r1 * cos(theta + theta1); p1[1] = this->CenterWorld[1] + r1 * sin(theta + theta1); p2[0] = this->CenterWorld[0] + r2 * cos(theta + theta2); p2[1] = this->CenterWorld[1] + r2 * sin(theta + theta2); p3[0] = this->CenterWorld[0] + r3 * cos(theta + theta3); p3[1] = this->CenterWorld[1] + r3 * sin(theta + theta3); p4[0] = this->CenterWorld[0] + r4 * cos(theta + theta4); p4[1] = this->CenterWorld[1] + r4 * sin(theta + theta4); p1[2] = this->P1World[2]; p2[2] = this->P2World[2]; p3[2] = this->P3World[2]; p4[2] = this->P4World[2]; this->SetPoint1WorldPosition(p1); this->SetPoint2WorldPosition(p2); this->SetPoint3WorldPosition(p3); this->SetPoint4WorldPosition(p4); } else if (this->InteractionState == OnL1Inner) { vtkLine::DistanceToLine(pw, this->P3World, this->P4World, t, closest); t = (t < 0.0 ? 0.0 : (t > 1.0 ? 1.0 : t)); for (int i = 0; i < 3; i++) { p1[i] = this->P1World[i] + (t - this->T43) * this->P43World[i]; p2[i] = this->P2World[i] + (t - this->T43) * this->P43World[i]; } // Set the positions of P1 and P2. this->SetPoint1WorldPosition(p1); this->SetPoint2WorldPosition(p2); } else if (this->InteractionState == OnL2Inner) { vtkLine::DistanceToLine(pw, this->P1World, this->P2World, t, closest); t = (t < 0.0 ? 0.0 : (t > 1.0 ? 1.0 : t)); for (int i = 0; i < 3; i++) { p3[i] = this->P3World[i] + (t - this->T21) * this->P21World[i]; p4[i] = this->P4World[i] + (t - this->T21) * this->P21World[i]; } // Set the positions of P3 and P4. this->SetPoint3WorldPosition(p3); this->SetPoint4WorldPosition(p4); } else if (this->InteractionState == NearP1) { this->ProjectOrthogonalPoint( pw, this->P2World, this->P3World, this->P4World, this->P43World, -1, p1); this->SetPoint1WorldPosition(p1); } else if (this->InteractionState == NearP2) { this->ProjectOrthogonalPoint( pw, this->P1World, this->P3World, this->P4World, this->P43World, 1, p2); this->SetPoint2WorldPosition(p2); } else if (this->InteractionState == NearP3) { this->ProjectOrthogonalPoint( pw, this->P4World, this->P1World, this->P2World, this->P21World, 1, p3); this->SetPoint3WorldPosition(p3); } else if (this->InteractionState == NearP4) { this->ProjectOrthogonalPoint( pw, this->P3World, this->P1World, this->P2World, this->P21World, -1, p4); this->SetPoint4WorldPosition(p4); } // near P4 } //------------------------------------------------------------------------------ void vtkBiDimensionalRepresentation2D::BuildRepresentation() { if (this->GetMTime() > this->BuildTime || this->Point1Representation->GetMTime() > this->BuildTime || this->Point2Representation->GetMTime() > this->BuildTime || this->Point3Representation->GetMTime() > this->BuildTime || this->Point4Representation->GetMTime() > this->BuildTime || (this->Renderer && this->Renderer->GetVTKWindow() && this->Renderer->GetVTKWindow()->GetMTime() > this->BuildTime)) { // Make sure that tolerance is consistent between handles and this representation this->Point1Representation->SetTolerance(this->Tolerance); this->Point2Representation->SetTolerance(this->Tolerance); this->Point3Representation->SetTolerance(this->Tolerance); this->Point4Representation->SetTolerance(this->Tolerance); // Now bring the lines up to date if (!this->Line1Visibility) { return; } char distStr1[256], distStr2[256]; double p1[3], p2[3], p3[3], p4[3]; this->GetPoint1DisplayPosition(p1); this->GetPoint2DisplayPosition(p2); this->GetPoint3DisplayPosition(p3); this->GetPoint4DisplayPosition(p4); double wp1[3], wp2[3], wp3[3], wp4[3]; this->GetPoint1WorldPosition(wp1); this->GetPoint2WorldPosition(wp2); this->GetPoint3WorldPosition(wp3); this->GetPoint4WorldPosition(wp4); this->LinePoints->SetPoint(0, p1); this->LinePoints->SetPoint(1, p2); this->LinePoints->SetPoint(2, p3); this->LinePoints->SetPoint(3, p4); this->LinePoints->Modified(); this->LineCells->Reset(); this->LineCells->InsertNextCell(2); this->LineCells->InsertCellPoint(0); this->LineCells->InsertCellPoint(1); if (this->Line2Visibility) { this->LineCells->InsertNextCell(2); this->LineCells->InsertCellPoint(2); this->LineCells->InsertCellPoint(3); } double line1Dist = sqrt(vtkMath::Distance2BetweenPoints(wp1, wp2)); double line2Dist = 0; if (this->Line2Visibility) { line2Dist = sqrt(vtkMath::Distance2BetweenPoints(wp3, wp4)); } std::ostringstream label; if (this->IDInitialized) { label << this->ID << ": "; } snprintf(distStr1, sizeof(distStr1), this->LabelFormat, line1Dist); snprintf(distStr2, sizeof(distStr2), this->LabelFormat, line2Dist); if (line1Dist > line2Dist) { label << distStr1 << " x " << distStr2; } else { label << distStr2 << " x " << distStr1; } this->TextMapper->SetInput(label.str().c_str()); // Adjust the font size int stringSize[2], *winSize = this->Renderer->GetSize(); vtkTextMapper::SetRelativeFontSize( this->TextMapper, this->Renderer, winSize, stringSize, 0.015); int maxX = VTK_INT_MIN, maxY = VTK_INT_MIN; if (p1[1] > maxY) { maxX = static_cast(p1[0]); maxY = static_cast(p1[1]); } if (p2[1] > maxY) { maxX = static_cast(p2[0]); maxY = static_cast(p2[1]); } if (p3[1] > maxY) { maxX = static_cast(p3[0]); maxY = static_cast(p3[1]); } if (p4[1] > maxY) { maxX = static_cast(p4[0]); maxY = static_cast(p4[1]); } int minX = VTK_INT_MAX, minY = VTK_INT_MAX; if (p1[1] < minY) { minX = static_cast(p1[0]); minY = static_cast(p1[1]); } if (p2[1] < minY) { minX = static_cast(p2[0]); minY = static_cast(p2[1]); } if (p3[1] < minY) { minX = static_cast(p3[0]); minY = static_cast(p3[1]); } if (p4[1] < minY) { minX = static_cast(p4[0]); minY = static_cast(p4[1]); } this->TextMapper->GetTextProperty()->SetJustificationToCentered(); if (this->ShowLabelAboveWidget) { this->TextActor->SetPosition(maxX, maxY + 9); this->TextMapper->GetTextProperty()->SetVerticalJustificationToBottom(); } else { this->TextActor->SetPosition(minX, minY - 9); this->TextMapper->GetTextProperty()->SetVerticalJustificationToTop(); } this->BuildTime.Modified(); } } //------------------------------------------------------------------------------ char* vtkBiDimensionalRepresentation2D::GetLabelText() { return this->TextMapper->GetInput(); } //------------------------------------------------------------------------------ double* vtkBiDimensionalRepresentation2D::GetLabelPosition() { return this->TextActor->GetPosition(); } //------------------------------------------------------------------------------ void vtkBiDimensionalRepresentation2D::GetLabelPosition(double pos[3]) { this->TextActor->GetPositionCoordinate()->GetValue(pos); } //------------------------------------------------------------------------------ void vtkBiDimensionalRepresentation2D::GetWorldLabelPosition(double pos[3]) { double viewportPos[3], worldPos[4]; pos[0] = pos[1] = pos[2] = 0.0; if (!this->Renderer) { vtkErrorMacro("GetWorldLabelPosition: no renderer!"); return; } this->TextActor->GetPositionCoordinate()->GetValue(viewportPos); this->Renderer->ViewportToNormalizedViewport(viewportPos[0], viewportPos[1]); this->Renderer->NormalizedViewportToView(viewportPos[0], viewportPos[1], viewportPos[2]); this->Renderer->SetViewPoint(viewportPos); this->Renderer->ViewToWorld(); this->Renderer->GetWorldPoint(worldPos); if (worldPos[3] != 0.0) { pos[0] = worldPos[0] / worldPos[3]; pos[1] = worldPos[1] / worldPos[3]; pos[2] = worldPos[2] / worldPos[3]; } else { vtkErrorMacro("GetWorldLabelPosition: world position at index 3 is 0, not dividing by 0"); } } //------------------------------------------------------------------------------ void vtkBiDimensionalRepresentation2D::ReleaseGraphicsResources(vtkWindow* w) { this->LineActor->ReleaseGraphicsResources(w); this->TextActor->ReleaseGraphicsResources(w); } //------------------------------------------------------------------------------ int vtkBiDimensionalRepresentation2D::RenderOverlay(vtkViewport* viewport) { this->BuildRepresentation(); int count = this->LineActor->RenderOverlay(viewport); if (this->Line1Visibility) { count += this->TextActor->RenderOverlay(viewport); } return count; } //------------------------------------------------------------------------------ void vtkBiDimensionalRepresentation2D::Highlight(int highlightOn) { if (highlightOn) { this->LineActor->SetProperty(this->SelectedLineProperty); } else { this->LineActor->SetProperty(this->LineProperty); } } //------------------------------------------------------------------------------ void vtkBiDimensionalRepresentation2D::PrintSelf(ostream& os, vtkIndent indent) { // Superclass typedef defined in vtkTypeMacro() found in vtkSetGet.h this->Superclass::PrintSelf(os, indent); if (this->TextProperty) { os << indent << "Text Property:\n"; this->TextProperty->PrintSelf(os, indent.GetNextIndent()); } else { os << indent << "Property: (none)\n"; } if (this->LineProperty) { os << indent << "Line Property:\n"; this->LineProperty->PrintSelf(os, indent.GetNextIndent()); } else { os << indent << "Line Property: (none)\n"; } if (this->SelectedLineProperty) { os << indent << "Selected Line Property:\n"; this->SelectedLineProperty->PrintSelf(os, indent.GetNextIndent()); } else { os << indent << "Selected Line Property: (none)\n"; } }