1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkCaptionActor2D.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 #include "vtkCaptionActor2D.h"
16 
17 #include "vtkActor.h"
18 #include "vtkAppendPolyData.h"
19 #include "vtkCellArray.h"
20 #include "vtkDoubleArray.h"
21 #include "vtkGlyph2D.h"
22 #include "vtkGlyph3D.h"
23 #include "vtkMath.h"
24 #include "vtkObjectFactory.h"
25 #include "vtkPointData.h"
26 #include "vtkPolyData.h"
27 #include "vtkPolyDataMapper.h"
28 #include "vtkPolyDataMapper2D.h"
29 #include "vtkProperty.h"
30 #include "vtkProperty2D.h"
31 #include "vtkTextActor.h"
32 #include "vtkTextProperty.h"
33 #include "vtkTrivialProducer.h"
34 #include "vtkViewport.h"
35 
36 vtkStandardNewMacro(vtkCaptionActor2D);
37 
38 vtkCxxSetObjectMacro(vtkCaptionActor2D, CaptionTextProperty, vtkTextProperty);
39 
40 class vtkCaptionActor2DConnection : public vtkAlgorithm
41 {
42 public:
43   static vtkCaptionActor2DConnection* New();
44   vtkTypeMacro(vtkCaptionActor2DConnection, vtkAlgorithm);
45 
vtkCaptionActor2DConnection()46   vtkCaptionActor2DConnection() { this->SetNumberOfInputPorts(1); }
47 };
48 
49 vtkStandardNewMacro(vtkCaptionActor2DConnection);
50 
51 //------------------------------------------------------------------------------
vtkCaptionActor2D()52 vtkCaptionActor2D::vtkCaptionActor2D()
53 {
54   // Positioning information
55   this->AttachmentPointCoordinate = vtkCoordinate::New();
56   this->AttachmentPointCoordinate->SetCoordinateSystemToWorld();
57   this->AttachmentPointCoordinate->SetValue(0.0, 0.0, 0.0);
58 
59   this->PositionCoordinate->SetCoordinateSystemToDisplay();
60   this->PositionCoordinate->SetReferenceCoordinate(this->AttachmentPointCoordinate);
61   this->PositionCoordinate->SetValue(static_cast<double>(10), static_cast<double>(10));
62 
63   // This sets up the Position2Coordinate
64   this->vtkActor2D::SetWidth(0.25);
65   this->vtkActor2D::SetHeight(0.10);
66 
67   this->Border = 1;
68   this->Leader = 1;
69   this->AttachEdgeOnly = 0;
70   this->ThreeDimensionalLeader = 1;
71   this->LeaderGlyphSize = 0.025;
72   this->MaximumLeaderGlyphSize = 20;
73 
74   this->LeaderGlyphConnectionHolder = vtkCaptionActor2DConnection::New();
75 
76   // Control font properties
77   this->Padding = 3;
78 
79   this->CaptionTextProperty = vtkTextProperty::New();
80   this->CaptionTextProperty->SetBold(1);
81   this->CaptionTextProperty->SetItalic(1);
82   this->CaptionTextProperty->SetShadow(1);
83   this->CaptionTextProperty->SetFontFamily(VTK_ARIAL);
84   this->CaptionTextProperty->SetJustification(VTK_TEXT_LEFT);
85   this->CaptionTextProperty->SetVerticalJustification(VTK_TEXT_BOTTOM);
86 
87   // What is actually drawn
88   this->TextActor = vtkTextActor::New();
89   this->TextActor->GetPositionCoordinate()->SetCoordinateSystemToDisplay();
90   this->TextActor->GetPositionCoordinate()->SetReferenceCoordinate(nullptr);
91   this->TextActor->GetPosition2Coordinate()->SetCoordinateSystemToDisplay();
92   this->TextActor->GetPosition2Coordinate()->SetReferenceCoordinate(nullptr);
93   this->TextActor->SetTextScaleModeToProp();
94   this->TextActor->SetTextProperty(this->CaptionTextProperty);
95 
96   this->BorderPolyData = vtkPolyData::New();
97   vtkPoints* pts = vtkPoints::New();
98   pts->SetNumberOfPoints(4);
99   this->BorderPolyData->SetPoints(pts);
100   pts->Delete();
101   vtkCellArray* border = vtkCellArray::New();
102   border->InsertNextCell(5);
103   border->InsertCellPoint(0);
104   border->InsertCellPoint(1);
105   border->InsertCellPoint(2);
106   border->InsertCellPoint(3);
107   border->InsertCellPoint(0);
108   this->BorderPolyData->SetLines(border);
109   border->Delete();
110 
111   this->BorderMapper = vtkPolyDataMapper2D::New();
112   this->BorderMapper->SetInputData(this->BorderPolyData);
113   this->BorderActor = vtkActor2D::New();
114   this->BorderActor->SetMapper(this->BorderMapper);
115 
116   // Set border mapper coordinate system to Display.
117   vtkCoordinate* coord = vtkCoordinate::New();
118   coord->SetCoordinateSystemToDisplay();
119   this->BorderMapper->SetTransformCoordinate(coord);
120   coord->Delete();
121 
122   // This is for glyphing the head of the leader
123   // A single point with a vector for glyph orientation
124   this->HeadPolyData = vtkPolyData::New();
125   pts = vtkPoints::New();
126   pts->SetNumberOfPoints(1);
127   this->HeadPolyData->SetPoints(pts);
128   pts->Delete();
129   vtkDoubleArray* vecs = vtkDoubleArray::New();
130   vecs->SetNumberOfComponents(3);
131   vecs->SetNumberOfTuples(1);
132   this->HeadPolyData->GetPointData()->SetVectors(vecs);
133   vecs->Delete();
134 
135   // This is the leader (line) from the attachment point to the caption
136   this->LeaderPolyData = vtkPolyData::New();
137   pts = vtkPoints::New();
138   pts->SetNumberOfPoints(2);
139   this->LeaderPolyData->SetPoints(pts);
140   pts->Delete();
141   vtkCellArray* leader = vtkCellArray::New();
142   leader->InsertNextCell(2);
143   leader->InsertCellPoint(0);
144   leader->InsertCellPoint(1); // at the attachment point
145   this->LeaderPolyData->SetLines(leader);
146   leader->Delete();
147 
148   // Used to generate the glyph on the leader head
149   this->HeadGlyph = vtkGlyph3D::New();
150   this->HeadGlyph->SetInputData(this->HeadPolyData);
151   this->HeadGlyph->SetScaleModeToDataScalingOff();
152   this->HeadGlyph->SetScaleFactor(0.1);
153 
154   // Appends the leader and the glyph head
155   this->AppendLeader = vtkAppendPolyData::New();
156   this->AppendLeader->AddInputData(this->LeaderPolyData);
157   this->AppendLeader->AddInputConnection(this->HeadGlyph->GetOutputPort());
158 
159   // Used to transform from world to other coordinate systems
160   this->MapperCoordinate2D = vtkCoordinate::New();
161   this->MapperCoordinate2D->SetCoordinateSystemToWorld();
162 
163   // If 2D leader is used, then use this mapper/actor combination
164   this->LeaderMapper2D = vtkPolyDataMapper2D::New();
165   this->LeaderMapper2D->SetTransformCoordinate(this->MapperCoordinate2D);
166   this->LeaderActor2D = vtkActor2D::New();
167   this->LeaderActor2D->SetMapper(this->LeaderMapper2D);
168 
169   // If 3D leader is used, then use this mapper/actor combination
170   this->LeaderMapper3D = vtkPolyDataMapper::New();
171   this->LeaderActor3D = vtkActor::New();
172   this->LeaderActor3D->SetMapper(this->LeaderMapper3D);
173 }
174 
175 //------------------------------------------------------------------------------
~vtkCaptionActor2D()176 vtkCaptionActor2D::~vtkCaptionActor2D()
177 {
178   this->AttachmentPointCoordinate->Delete();
179 
180   this->TextActor->Delete();
181 
182   this->LeaderGlyphConnectionHolder->Delete();
183   this->LeaderGlyphConnectionHolder = nullptr;
184 
185   this->BorderPolyData->Delete();
186   this->BorderMapper->Delete();
187   this->BorderActor->Delete();
188 
189   this->HeadPolyData->Delete();
190   this->LeaderPolyData->Delete();
191   this->HeadGlyph->Delete();
192   this->AppendLeader->Delete();
193 
194   this->MapperCoordinate2D->Delete();
195 
196   this->LeaderMapper2D->Delete();
197   this->LeaderActor2D->Delete();
198 
199   this->LeaderMapper3D->Delete();
200   this->LeaderActor3D->Delete();
201 
202   this->SetCaptionTextProperty(nullptr);
203 }
204 
205 //------------------------------------------------------------------------------
SetLeaderGlyphConnection(vtkAlgorithmOutput * ao)206 void vtkCaptionActor2D::SetLeaderGlyphConnection(vtkAlgorithmOutput* ao)
207 {
208   this->LeaderGlyphConnectionHolder->SetInputConnection(ao);
209 }
210 
211 //------------------------------------------------------------------------------
SetLeaderGlyphData(vtkPolyData * leader)212 void vtkCaptionActor2D::SetLeaderGlyphData(vtkPolyData* leader)
213 {
214   vtkTrivialProducer* tp = vtkTrivialProducer::New();
215   tp->SetOutput(leader);
216   this->SetLeaderGlyphConnection(tp->GetOutputPort());
217   tp->Delete();
218 }
219 
220 //------------------------------------------------------------------------------
GetLeaderGlyph()221 vtkPolyData* vtkCaptionActor2D::GetLeaderGlyph()
222 {
223   if (this->LeaderGlyphConnectionHolder->GetNumberOfInputConnections(0) < 1)
224   {
225     return nullptr;
226   }
227   return vtkPolyData::SafeDownCast(this->LeaderGlyphConnectionHolder->GetInputDataObject(0, 0));
228 }
229 
230 //------------------------------------------------------------------------------
SetCaption(const char * caption)231 void vtkCaptionActor2D::SetCaption(const char* caption)
232 {
233   this->TextActor->SetInput(caption);
234 }
235 
236 //------------------------------------------------------------------------------
GetCaption()237 char* vtkCaptionActor2D::GetCaption()
238 {
239   return this->TextActor->GetInput();
240 }
241 
242 //------------------------------------------------------------------------------
243 // Release any graphics resources that are being consumed by this actor.
244 // The parameter window could be used to determine which graphic
245 // resources to release.
ReleaseGraphicsResources(vtkWindow * win)246 void vtkCaptionActor2D::ReleaseGraphicsResources(vtkWindow* win)
247 {
248   this->TextActor->ReleaseGraphicsResources(win);
249   this->BorderActor->ReleaseGraphicsResources(win);
250   this->LeaderActor2D->ReleaseGraphicsResources(win);
251   this->LeaderActor3D->ReleaseGraphicsResources(win);
252 }
253 
RenderOverlay(vtkViewport * viewport)254 int vtkCaptionActor2D::RenderOverlay(vtkViewport* viewport)
255 {
256   int renderedSomething = 0;
257 
258   renderedSomething += this->TextActor->RenderOverlay(viewport);
259 
260   if (this->Border)
261   {
262     renderedSomething += this->BorderActor->RenderOverlay(viewport);
263   }
264 
265   if (this->Leader)
266   {
267     if (this->ThreeDimensionalLeader)
268     {
269       renderedSomething += this->LeaderActor3D->RenderOverlay(viewport);
270     }
271     else
272     {
273       renderedSomething += this->LeaderActor2D->RenderOverlay(viewport);
274     }
275   }
276 
277   return renderedSomething;
278 }
279 
280 //------------------------------------------------------------------------------
RenderOpaqueGeometry(vtkViewport * viewport)281 int vtkCaptionActor2D::RenderOpaqueGeometry(vtkViewport* viewport)
282 {
283   // Build the caption (almost always needed so we don't check mtime)
284   vtkDebugMacro(<< "Rebuilding caption");
285 
286   // compute coordinates and set point values
287   //
288   double *w1, *w2;
289   int *x1, *x2, *x3;
290   double p1[4], p2[4], p3[4];
291   x1 = this->AttachmentPointCoordinate->GetComputedDisplayValue(viewport);
292   x2 = this->PositionCoordinate->GetComputedDisplayValue(viewport);
293   x3 = this->Position2Coordinate->GetComputedDisplayValue(viewport);
294   p1[0] = (double)x1[0];
295   p1[1] = (double)x1[1];
296   p1[2] = 0.0;
297   p2[0] = (double)x2[0];
298   p2[1] = (double)x2[1];
299   p2[2] = p1[2];
300   p3[0] = (double)x3[0];
301   p3[1] = (double)x3[1];
302   p3[2] = p1[2];
303 
304   // Set up the scaled text - take into account the padding
305   this->TextActor->SetTextProperty(this->CaptionTextProperty);
306   this->TextActor->GetPositionCoordinate()->SetValue(
307     p2[0] + this->Padding, p2[1] + this->Padding, 0.0);
308   this->TextActor->GetPosition2Coordinate()->SetValue(
309     p3[0] - this->Padding, p3[1] - this->Padding, 0.0);
310 
311   // Define the border
312   vtkPoints* pts = this->BorderPolyData->GetPoints();
313   pts->SetPoint(0, p2);
314   pts->SetPoint(1, p3[0], p2[1], p1[2]);
315   pts->SetPoint(2, p3[0], p3[1], p1[2]);
316   pts->SetPoint(3, p2[0], p3[1], p1[2]);
317 
318   // Define the leader. Have to find the closest point from the
319   // border to the attachment point. We look at the four vertices
320   // and four edge centers.
321   double d2, minD2, pt[3], minPt[3];
322   minD2 = VTK_DOUBLE_MAX;
323 
324   minPt[0] = p2[0];
325   minPt[1] = p2[1];
326 
327   pt[0] = p2[0];
328   pt[1] = p2[1];
329   pt[2] = minPt[2] = 0.0;
330   if (!this->AttachEdgeOnly && (d2 = vtkMath::Distance2BetweenPoints(p1, pt)) < minD2)
331   {
332     minD2 = d2;
333     minPt[0] = pt[0];
334     minPt[1] = pt[1];
335   }
336 
337   pt[0] = (p2[0] + p3[0]) / 2.0;
338   if ((d2 = vtkMath::Distance2BetweenPoints(p1, pt)) < minD2)
339   {
340     minD2 = d2;
341     minPt[0] = pt[0];
342     minPt[1] = pt[1];
343   }
344 
345   pt[0] = p3[0];
346   if (!this->AttachEdgeOnly && (d2 = vtkMath::Distance2BetweenPoints(p1, pt)) < minD2)
347   {
348     minD2 = d2;
349     minPt[0] = pt[0];
350     minPt[1] = pt[1];
351   }
352 
353   pt[1] = (p2[1] + p3[1]) / 2.0;
354   if ((d2 = vtkMath::Distance2BetweenPoints(p1, pt)) < minD2)
355   {
356     minD2 = d2;
357     minPt[0] = pt[0];
358     minPt[1] = pt[1];
359   }
360 
361   pt[1] = p3[1];
362   if (!this->AttachEdgeOnly && (d2 = vtkMath::Distance2BetweenPoints(p1, pt)) < minD2)
363   {
364     minD2 = d2;
365     minPt[0] = pt[0];
366     minPt[1] = pt[1];
367   }
368 
369   pt[0] = (p2[0] + p3[0]) / 2.0;
370   if ((d2 = vtkMath::Distance2BetweenPoints(p1, pt)) < minD2)
371   {
372     minD2 = d2;
373     minPt[0] = pt[0];
374     minPt[1] = pt[1];
375   }
376 
377   pt[0] = p2[0];
378   if (!this->AttachEdgeOnly && (d2 = vtkMath::Distance2BetweenPoints(p1, pt)) < minD2)
379   {
380     minD2 = d2;
381     minPt[0] = pt[0];
382     minPt[1] = pt[1];
383   }
384 
385   pt[1] = (p2[1] + p3[1]) / 2.0;
386   if ((d2 = vtkMath::Distance2BetweenPoints(p1, pt)) < minD2)
387   {
388     minD2 = d2;
389     minPt[0] = pt[0];
390     minPt[1] = pt[1];
391   }
392 
393   // Set the leader coordinates in appropriate coordinate system
394   // The pipeline is connected differently depending on the dimension
395   // and availability of a leader head.
396   if (this->Leader)
397   {
398     pts = this->LeaderPolyData->GetPoints();
399 
400     w1 = this->AttachmentPointCoordinate->GetComputedWorldValue(viewport);
401     viewport->SetWorldPoint(w1[0], w1[1], w1[2], 1.0);
402     viewport->WorldToView();
403     viewport->GetViewPoint(p1);
404 
405     // minPt is in display coordinates and it is OK
406     double val[3];
407     val[0] = minPt[0];
408     val[1] = minPt[1];
409     val[2] = 0;
410     // convert to view
411     viewport->DisplayToNormalizedDisplay(val[0], val[1]);
412     viewport->NormalizedDisplayToViewport(val[0], val[1]);
413     viewport->ViewportToNormalizedViewport(val[0], val[1]);
414     viewport->NormalizedViewportToView(val[0], val[1], val[2]);
415 
416     // use the zvalue from the attach point
417     val[2] = p1[2];
418     viewport->SetViewPoint(val);
419     viewport->ViewToWorld();
420     double w3[4];
421     viewport->GetWorldPoint(w3);
422     if (w3[3] != 0.0)
423     {
424       w3[0] /= w3[3];
425       w3[1] /= w3[3];
426       w3[2] /= w3[3];
427     }
428     w2 = w3;
429 
430     pts->SetPoint(0, w1);
431     pts->SetPoint(1, w2);
432     this->HeadPolyData->GetPoints()->SetPoint(0, w1);
433     this->HeadPolyData->GetPointData()->GetVectors()->SetTuple3(
434       0, w1[0] - w2[0], w1[1] - w2[1], w1[2] - w2[2]);
435 
436     pts->Modified();
437     this->HeadPolyData->Modified();
438   }
439 
440   if (this->GetLeaderGlyph())
441   {
442     this->LeaderGlyphConnectionHolder->GetInputAlgorithm()->Update();
443 
444     // compute the scale
445     double length = this->GetLeaderGlyph()->GetLength();
446     const int* sze = viewport->GetSize();
447     int numPixels = static_cast<int>(
448       this->LeaderGlyphSize * sqrt(static_cast<double>(sze[0] * sze[0] + sze[1] * sze[1])));
449     numPixels =
450       (numPixels > this->MaximumLeaderGlyphSize ? this->MaximumLeaderGlyphSize : numPixels);
451 
452     // determine the number of units length per pixel
453     viewport->SetDisplayPoint(sze[0] / 2, sze[1] / 2, 0);
454     viewport->DisplayToWorld();
455     viewport->GetWorldPoint(p1);
456     if (p1[3] != 0.0)
457     {
458       p1[0] /= p1[3];
459       p1[1] /= p1[3];
460       p1[2] /= p1[3];
461     }
462 
463     viewport->SetDisplayPoint(sze[0] / 2 + 1, sze[1] / 2 + 1, 0);
464     viewport->DisplayToWorld();
465     viewport->GetWorldPoint(p2);
466     if (p2[3] != 0.0)
467     {
468       p2[0] /= p2[3];
469       p2[1] /= p2[3];
470       p2[2] /= p2[3];
471     }
472 
473     // Arbitrary 1.5 factor makes up for the use of "diagonals" in length
474     // calculations; otherwise the scale factor tends to be too small
475     double sf = 1.5 * numPixels * sqrt(vtkMath::Distance2BetweenPoints(p1, p2)) / length;
476 
477     vtkDebugMacro(<< "Scale factor: " << sf);
478 
479     this->HeadGlyph->SetSourceData(this->GetLeaderGlyph());
480     this->HeadGlyph->SetScaleFactor(sf);
481 
482     this->LeaderMapper2D->SetInputConnection(this->AppendLeader->GetOutputPort());
483     this->LeaderMapper3D->SetInputConnection(this->AppendLeader->GetOutputPort());
484     this->AppendLeader->Update();
485   }
486   else
487   {
488     this->LeaderMapper2D->SetInputData(this->LeaderPolyData);
489     this->LeaderMapper3D->SetInputData(this->LeaderPolyData);
490   }
491 
492   // assign properties
493   //
494   this->BorderActor->SetProperty(this->GetProperty());
495   this->LeaderActor2D->SetProperty(this->GetProperty());
496   this->LeaderActor3D->GetProperty()->SetColor(this->GetProperty()->GetColor());
497   // Copy the property into the text actor and reset the color -- otherwise the
498   // text shadow will be colored the same as the text.
499   this->TextActor->GetProperty()->DeepCopy(this->GetProperty());
500   this->TextActor->GetProperty()->SetColor(1.0, 1.0, 1.0);
501   this->TextActor->GetProperty()->SetOpacity(1.0);
502 
503   // Okay we are ready to render something
504   int renderedSomething = 0;
505   renderedSomething += this->TextActor->RenderOpaqueGeometry(viewport);
506   if (this->Border)
507   {
508     renderedSomething += this->BorderActor->RenderOpaqueGeometry(viewport);
509   }
510 
511   if (this->Leader)
512   {
513     if (this->ThreeDimensionalLeader)
514     {
515       renderedSomething += this->LeaderActor3D->RenderOpaqueGeometry(viewport);
516     }
517     else
518     {
519       renderedSomething += this->LeaderActor2D->RenderOpaqueGeometry(viewport);
520     }
521   }
522 
523   return renderedSomething;
524 }
525 
526 //------------------------------------------------------------------------------
527 // Description:
528 // Does this prop have some translucent polygonal geometry?
HasTranslucentPolygonalGeometry()529 vtkTypeBool vtkCaptionActor2D::HasTranslucentPolygonalGeometry()
530 {
531   return 0;
532 }
533 
534 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)535 void vtkCaptionActor2D::PrintSelf(ostream& os, vtkIndent indent)
536 {
537   this->Superclass::PrintSelf(os, indent);
538 
539   os << indent << "Text Actor: " << this->TextActor << "\n";
540   if (this->CaptionTextProperty)
541   {
542     os << indent << "Caption Text Property:\n";
543     this->CaptionTextProperty->PrintSelf(os, indent.GetNextIndent());
544   }
545   else
546   {
547     os << indent << "Caption Text Property: (none)\n";
548   }
549 
550   os << indent << "Caption: ";
551   if (this->TextActor->GetInput())
552   {
553     os << this->TextActor->GetInput() << "\n";
554   }
555   else
556   {
557     os << "(none)\n";
558   }
559 
560   os << indent << "Leader: " << (this->Leader ? "On\n" : "Off\n");
561   os << indent << "Three Dimensional Leader: " << (this->ThreeDimensionalLeader ? "On\n" : "Off\n");
562   os << indent << "Leader Glyph Size: " << this->LeaderGlyphSize << "\n";
563   os << indent << "MaximumLeader Glyph Size: " << this->MaximumLeaderGlyphSize << "\n";
564   if (!this->GetLeaderGlyph())
565   {
566     os << indent << "Leader Glyph: (none)\n";
567   }
568   else
569   {
570     os << indent << "Leader Glyph: (" << this->GetLeaderGlyph() << ")\n";
571   }
572   os << indent << "Padding: " << this->Padding << "\n";
573   os << indent << "Border: " << (this->Border ? "On\n" : "Off\n");
574   os << indent << "AttachEdgeOnly: " << (this->AttachEdgeOnly ? "On\n" : "Off\n");
575 }
576 
577 //------------------------------------------------------------------------------
ShallowCopy(vtkProp * prop)578 void vtkCaptionActor2D::ShallowCopy(vtkProp* prop)
579 {
580   vtkCaptionActor2D* a = vtkCaptionActor2D::SafeDownCast(prop);
581   if (a != nullptr)
582   {
583     this->SetCaption(a->GetCaption());
584     this->SetAttachmentPoint(a->GetAttachmentPoint());
585     this->SetBorder(a->GetBorder());
586     this->SetLeader(a->GetLeader());
587     this->SetThreeDimensionalLeader(a->GetThreeDimensionalLeader());
588     if (a->LeaderGlyphConnectionHolder->GetNumberOfInputConnections(0) < 1)
589     {
590       this->SetLeaderGlyphConnection(nullptr);
591     }
592     else
593     {
594       this->SetLeaderGlyphConnection(a->LeaderGlyphConnectionHolder->GetInputConnection(0, 0));
595     }
596     this->SetLeaderGlyphSize(a->GetLeaderGlyphSize());
597     this->SetMaximumLeaderGlyphSize(a->GetMaximumLeaderGlyphSize());
598     this->SetPadding(a->GetPadding());
599     this->SetCaptionTextProperty(a->GetCaptionTextProperty());
600   }
601 
602   // Now do superclass
603   this->vtkActor2D::ShallowCopy(prop);
604 }
605