vtkDataRepresentation.cxx 12.7 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkDataRepresentation.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.

=========================================================================*/
15
16
17
18
19
/*-------------------------------------------------------------------------
  Copyright 2008 Sandia Corporation.
  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
  the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------*/
20
21
22

#include "vtkDataRepresentation.h"

23
#include "vtkAlgorithmOutput.h"
24
#include "vtkAnnotationLayers.h"
25
#include "vtkAnnotationLink.h"
26
#include "vtkCommand.h"
27
#include "vtkConvertSelectionDomain.h"
28
#include "vtkDataObject.h"
29
#include "vtkDataSet.h"
Jeff Baumes's avatar
Jeff Baumes committed
30
#include "vtkDemandDrivenPipeline.h"
31
32
#include "vtkInformation.h"
#include "vtkInformationVector.h"
33
#include "vtkObjectFactory.h"
34
#include "vtkSelection.h"
Jeff Baumes's avatar
Jeff Baumes committed
35
#include "vtkSelectionNode.h"
36
#include "vtkSmartPointer.h"
Jeff Baumes's avatar
Jeff Baumes committed
37
#include "vtkStringArray.h"
38
#include "vtkTrivialProducer.h"
39

Jeff Baumes's avatar
Jeff Baumes committed
40
#include <vtkstd/map>
41
42

//---------------------------------------------------------------------------
Jeff Baumes's avatar
Jeff Baumes committed
43
// vtkDataRepresentation::Internals
44
45
//---------------------------------------------------------------------------

Jeff Baumes's avatar
Jeff Baumes committed
46
class vtkDataRepresentation::Internals {
47
48
public:

Jeff Baumes's avatar
Jeff Baumes committed
49
  // This is a cache of shallow copies of inputs provided for convenience.
50
51
  // It is a map from (port index, connection index) to (original input data port, shallow copy port).
  // NOTE: The original input data port pointer is not reference counted, so it should
Jeff Baumes's avatar
Jeff Baumes committed
52
53
  // not be assumed to be a valid pointer. It is only used for pointer comparison.
  vtkstd::map<vtkstd::pair<int, int>,
Berk Geveci's avatar
Berk Geveci committed
54
              vtkstd::pair<vtkAlgorithmOutput*, vtkSmartPointer<vtkTrivialProducer> > >
Jeff Baumes's avatar
Jeff Baumes committed
55
56
57
58
59
60
61
    InputInternal;

  // This is a cache of vtkConvertSelectionDomain filters provided for convenience.
  // It is a map from (port index, connection index) to convert selection domain filter.
  vtkstd::map<vtkstd::pair<int, int>, vtkSmartPointer<vtkConvertSelectionDomain> >
    ConvertDomainInternal;
};
62

Jeff Baumes's avatar
Jeff Baumes committed
63
64
65
//---------------------------------------------------------------------------
// vtkDataRepresentation::Command
//----------------------------------------------------------------------------
66

Jeff Baumes's avatar
Jeff Baumes committed
67
68
69
70
71
72
class vtkDataRepresentation::Command : public vtkCommand
{
public:
  static Command* New() {  return new Command(); }
  virtual void Execute(vtkObject *caller, unsigned long eventId,
                       void *callData)
73
    {
Jeff Baumes's avatar
Jeff Baumes committed
74
75
76
77
    if (this->Target)
      {
      this->Target->ProcessEvents(caller, eventId, callData);
      }
78
    }
Jeff Baumes's avatar
Jeff Baumes committed
79
  void SetTarget(vtkDataRepresentation* t)
80
    {
Jeff Baumes's avatar
Jeff Baumes committed
81
    this->Target = t;
82
    }
Jeff Baumes's avatar
Jeff Baumes committed
83
84
85
private:
  Command() { this->Target = 0; }
  vtkDataRepresentation* Target;
86
87
88
89
90
91
};

//----------------------------------------------------------------------------
// vtkDataRepresentation
//----------------------------------------------------------------------------

92
vtkStandardNewMacro(vtkDataRepresentation);
93
94
vtkCxxSetObjectMacro(vtkDataRepresentation,
  AnnotationLinkInternal, vtkAnnotationLink);
Jeff Baumes's avatar
Jeff Baumes committed
95
vtkCxxSetObjectMacro(vtkDataRepresentation, SelectionArrayNames, vtkStringArray);
96

97
//----------------------------------------------------------------------------
Dave Partyka's avatar
Dave Partyka committed
98
vtkDataRepresentation::vtkDataRepresentation()
99
{
Dave Partyka's avatar
Dave Partyka committed
100
  this->Implementation = new vtkDataRepresentation::Internals();
Jeff Baumes's avatar
Jeff Baumes committed
101
102
103
104
105
  // Listen to event indicating that the algorithm is done executing.
  // We may need to clear the data object cache after execution.
  this->Observer = Command::New();
  this->AddObserver(vtkCommand::EndEvent, this->Observer);
  
106
  this->Selectable = true;
Jeff Baumes's avatar
Jeff Baumes committed
107
108
  this->SelectionArrayNames = vtkStringArray::New();
  this->SelectionType = vtkSelectionNode::INDICES;
109
110
  this->AnnotationLinkInternal = vtkAnnotationLink::New();
  this->SetNumberOfOutputPorts(0);
111
112
113
114
115
}

//----------------------------------------------------------------------------
vtkDataRepresentation::~vtkDataRepresentation()
{
116
  delete this->Implementation;
Jeff Baumes's avatar
Jeff Baumes committed
117
118
  this->Observer->Delete();
  this->SetSelectionArrayNames(0);
119
  this->SetAnnotationLinkInternal(0);
120
121
}

122
123
124
125
126
127
128
//----------------------------------------------------------------------------
void vtkDataRepresentation::SetAnnotationLink(vtkAnnotationLink* link)
{
  this->SetAnnotationLinkInternal(link);
}

//----------------------------------------------------------------------------
Jeff Baumes's avatar
Jeff Baumes committed
129
void vtkDataRepresentation::ProcessEvents(vtkObject *caller, unsigned long eventId, void *vtkNotUsed(callData))
130
{
Jeff Baumes's avatar
Jeff Baumes committed
131
132
133
  // After the algorithm executes, if the release data flag is on,
  // clear the input shallow copy cache.
  if (caller == this && eventId == vtkCommand::EndEvent)
134
    {
Jeff Baumes's avatar
Jeff Baumes committed
135
136
    // Release input data if requested.
    for (int i = 0; i < this->GetNumberOfInputPorts(); ++i)
137
      {
Jeff Baumes's avatar
Jeff Baumes committed
138
139
140
141
142
143
144
145
146
147
148
149
      for (int j = 0; j < this->GetNumberOfInputConnections(i); ++j)
        {
        vtkInformation* inInfo = this->GetExecutive()->GetInputInformation(i, j);
        vtkDataObject* dataObject = inInfo->Get(vtkDataObject::DATA_OBJECT());
        if (dataObject && (dataObject->GetGlobalReleaseDataFlag() ||
            inInfo->Get(vtkDemandDrivenPipeline::RELEASE_DATA())))
          {
          vtkstd::pair<int, int> p(i, j);
          this->Implementation->InputInternal.erase(p);
          this->Implementation->ConvertDomainInternal.erase(p);
          }
        }
150
      }
151
    }
152
153
154
}

//----------------------------------------------------------------------------
Jeff Baumes's avatar
Jeff Baumes committed
155
vtkAlgorithmOutput* vtkDataRepresentation::GetInternalOutputPort(int port, int conn)
156
{
Jeff Baumes's avatar
Jeff Baumes committed
157
158
  if (port >= this->GetNumberOfInputPorts() ||
    conn >= this->GetNumberOfInputConnections(port))
159
    {
Jeff Baumes's avatar
Jeff Baumes committed
160
161
162
    vtkErrorMacro("Port " << port << ", connection "
      << conn << " is not defined on this representation.");
    return 0;
163
164
    }

Jeff Baumes's avatar
Jeff Baumes committed
165
166
167
168
  // The cached shallow copy is out of date when the input data object
  // changed, or the shallow copy modified time is less than the
  // input modified time.
  vtkstd::pair<int, int> p(port, conn);
169
  vtkAlgorithmOutput* input = this->GetInputConnection(port, conn);
Jeff Baumes's avatar
Jeff Baumes committed
170
171
  if (this->Implementation->InputInternal.find(p) ==
    this->Implementation->InputInternal.end() ||
172
    this->Implementation->InputInternal[p].first != input)
173
    {
Jeff Baumes's avatar
Jeff Baumes committed
174
    this->Implementation->InputInternal[p].first = input;
175
176
    vtkDataObject* input = this->GetInputDataObject(port, conn);
    vtkDataObject* copy = input->NewInstance();
177
//     copy->ShallowCopy(input);
178
    vtkTrivialProducer* tp = vtkTrivialProducer::New();
179
    tp->SetOutput(input);
Berk Geveci's avatar
Berk Geveci committed
180
    this->Implementation->InputInternal[p].second = tp;
181
    tp->Delete();
182
    }
Jeff Baumes's avatar
Jeff Baumes committed
183

Berk Geveci's avatar
Berk Geveci committed
184
  return this->Implementation->InputInternal[p].second->GetOutputPort();
185
186
187
}

//----------------------------------------------------------------------------
Jeff Baumes's avatar
Jeff Baumes committed
188
189
vtkAlgorithmOutput* vtkDataRepresentation::GetInternalAnnotationOutputPort(
  int port, int conn)
190
{
Jeff Baumes's avatar
Jeff Baumes committed
191
192
  if (port >= this->GetNumberOfInputPorts() ||
    conn >= this->GetNumberOfInputConnections(port))
193
    {
Jeff Baumes's avatar
Jeff Baumes committed
194
195
196
    vtkErrorMacro("Port " << port << ", connection "
      << conn << " is not defined on this representation.");
    return 0;
197
    }
Jeff Baumes's avatar
Jeff Baumes committed
198
199
200
201
202

  // Create a new filter in the cache if necessary.
  vtkstd::pair<int, int> p(port, conn);
  if (this->Implementation->ConvertDomainInternal.find(p) ==
    this->Implementation->ConvertDomainInternal.end())
203
    {
Jeff Baumes's avatar
Jeff Baumes committed
204
205
    this->Implementation->ConvertDomainInternal[p] =
      vtkSmartPointer<vtkConvertSelectionDomain>::New();
206
207
    }

Jeff Baumes's avatar
Jeff Baumes committed
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
  // Set up the inputs to the cached filter.
  vtkConvertSelectionDomain* domain = this->Implementation->ConvertDomainInternal[p];
  domain->SetInputConnection(0,
    this->GetAnnotationLink()->GetOutputPort(0));
  domain->SetInputConnection(1,
    this->GetAnnotationLink()->GetOutputPort(1));
  domain->SetInputConnection(2,
    this->GetInternalOutputPort(port, conn));

  // Output port 0 of the convert domain filter is the linked
  // annotation(s) (the vtkAnnotationLayers object).
  return domain->GetOutputPort();
}

//----------------------------------------------------------------------------
vtkAlgorithmOutput* vtkDataRepresentation::GetInternalSelectionOutputPort(
  int port, int conn)
{
  // First make sure the convert domain filter is up to date.
  if (!this->GetInternalAnnotationOutputPort(port, conn))
228
    {
Jeff Baumes's avatar
Jeff Baumes committed
229
    return 0;
230
    }
Jeff Baumes's avatar
Jeff Baumes committed
231
232
233
234

  // Output port 1 of the convert domain filter is the current selection
  // that was contained in the linked annotation.
  vtkstd::pair<int, int> p(port, conn);
Dave Partyka's avatar
Dave Partyka committed
235
236
237
238
239
240
  if (this->Implementation->ConvertDomainInternal.find(p) !=
    this->Implementation->ConvertDomainInternal.end())
    {
    return this->Implementation->ConvertDomainInternal[p]->GetOutputPort(1);
    }
  return NULL;
241
242
}

243
244
//----------------------------------------------------------------------------
void vtkDataRepresentation::Select(
245
  vtkView* view, vtkSelection* selection, bool extend)
246
{
247
  if (this->Selectable)
248
    {
249
250
251
    vtkSelection* converted = this->ConvertSelection(view, selection);
    if (converted)
      {
252
      this->UpdateSelection(converted, extend);
253
254
255
256
      if (converted != selection)
        {
        converted->Delete();
        }
257
      }
258
259
260
261
262
263
264
    }
}

//----------------------------------------------------------------------------
vtkSelection* vtkDataRepresentation::ConvertSelection(
  vtkView* vtkNotUsed(view), vtkSelection* selection)
{
265
  return selection;
266
267
268
}

//----------------------------------------------------------------------------
269
void vtkDataRepresentation::UpdateSelection(vtkSelection* selection, bool extend)
270
{
271
272
273
274
  if (extend)
    {
    selection->Union(this->AnnotationLinkInternal->GetCurrentSelection());
    }
Jeff Baumes's avatar
Jeff Baumes committed
275
  this->AnnotationLinkInternal->SetCurrentSelection(selection);
276
277
278
  this->InvokeEvent(vtkCommand::SelectionChangedEvent, reinterpret_cast<void*>(selection));
}

279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308

//----------------------------------------------------------------------------
void vtkDataRepresentation::Annotate(
  vtkView* view, vtkAnnotationLayers* annotations, bool extend)
{
  vtkAnnotationLayers* converted = this->ConvertAnnotations(view, annotations);
  if (converted)
    {
    this->UpdateAnnotations(converted, extend);
    if (converted != annotations)
      {
      converted->Delete();
      }
    }
}

//----------------------------------------------------------------------------
vtkAnnotationLayers* vtkDataRepresentation::ConvertAnnotations(
  vtkView* vtkNotUsed(view), vtkAnnotationLayers* annotations)
{
  return annotations;
}

//----------------------------------------------------------------------------
void vtkDataRepresentation::UpdateAnnotations(vtkAnnotationLayers* annotations, bool extend)
{
  if (extend)
    {
    // Append the annotations to the existing set of annotations on the link
    vtkAnnotationLayers* currentAnnotations = this->AnnotationLinkInternal->GetAnnotationLayers();
Eric Stanton's avatar
Eric Stanton committed
309
    for(unsigned int i=0; i<annotations->GetNumberOfAnnotations(); ++i)
310
311
312
313
314
315
316
317
318
319
320
321
      {
      currentAnnotations->AddAnnotation(annotations->GetAnnotation(i));
      }
    this->InvokeEvent(vtkCommand::AnnotationChangedEvent, reinterpret_cast<void*>(currentAnnotations));
    }
  else
    {
    this->AnnotationLinkInternal->SetAnnotationLayers(annotations);
    this->InvokeEvent(vtkCommand::AnnotationChangedEvent, reinterpret_cast<void*>(annotations));
    }
}

Jeff Baumes's avatar
Jeff Baumes committed
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
//----------------------------------------------------------------------------
void vtkDataRepresentation::SetSelectionArrayName(const char* name)
{
  if (!this->SelectionArrayNames)
    {
    this->SelectionArrayNames = vtkStringArray::New();
    }
  this->SelectionArrayNames->Initialize();
  this->SelectionArrayNames->InsertNextValue(name);
}

//----------------------------------------------------------------------------
const char* vtkDataRepresentation::GetSelectionArrayName()
{
  if (this->SelectionArrayNames &&
      this->SelectionArrayNames->GetNumberOfTuples() > 0)
    {
    return this->SelectionArrayNames->GetValue(0);
    }
  return 0;
}

344
345
346
//----------------------------------------------------------------------------
void vtkDataRepresentation::PrintSelf(ostream& os, vtkIndent indent)
{
347
348
349
350
351
352
  this->Superclass::PrintSelf(os, indent);
  os << indent << "AnnotationLink: " << (this->AnnotationLinkInternal ? "" : "(null)") << endl;
  if (this->AnnotationLinkInternal)
    {
    this->AnnotationLinkInternal->PrintSelf(os, indent.GetNextIndent());
    }  
353
  os << indent << "Selectable: " << this->Selectable << endl;
Jeff Baumes's avatar
Jeff Baumes committed
354
355
356
357
358
359
  os << indent << "SelectionType: " << this->SelectionType << endl;
  os << indent << "SelectionArrayNames: " << (this->SelectionArrayNames ? "" : "(null)") << endl;
  if (this->SelectionArrayNames)
    {
    this->SelectionArrayNames->PrintSelf(os, indent.GetNextIndent());
    }
360
}