vtkAnnotationLink.cxx 9.87 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkAnnotationLink.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 "vtkAnnotationLink.h"

#include "vtkCommand.h"
#include "vtkDataObjectCollection.h"
#include "vtkIdTypeArray.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkObjectFactory.h"
#include "vtkAnnotationLayers.h"
26
#include "vtkSelection.h"
27 28 29 30
#include "vtkSmartPointer.h"
#include "vtkTable.h"

vtkStandardNewMacro(vtkAnnotationLink);
31 32 33 34 35
//vtkCxxSetObjectMacro(vtkAnnotationLink, AnnotationLayers, vtkAnnotationLayers);


//---------------------------------------------------------------------------
// vtkAnnotationLink::Command
36
//----------------------------------------------------------------------------
37 38

class vtkAnnotationLink::Command : public vtkCommand
39
{
40 41
public:
  static Command* New() {  return new Command(); }
42
  void Execute(vtkObject *caller, unsigned long eventId,
43
                       void *callData) override
44
  {
45
    if (this->Target)
46
    {
47 48
      this->Target->ProcessEvents(caller, eventId, callData);
    }
49
  }
50
  void SetTarget(vtkAnnotationLink* t)
51
  {
52
    this->Target = t;
53
  }
54
private:
55
  Command() { this->Target = nullptr; }
56 57 58 59 60
  vtkAnnotationLink* Target;
};

//----------------------------------------------------------------------------
vtkAnnotationLink::vtkAnnotationLink()
61
{
62
  this->SetNumberOfInputPorts(2);
63
  this->SetNumberOfOutputPorts(3);
64
  this->AnnotationLayers = vtkAnnotationLayers::New();
65
  this->DomainMaps = vtkDataObjectCollection::New();
66 67 68 69

  this->Observer = Command::New();
  this->Observer->SetTarget(this);
  this->AnnotationLayers->AddObserver(vtkCommand::ModifiedEvent, this->Observer);
70 71 72 73 74
}

//----------------------------------------------------------------------------
vtkAnnotationLink::~vtkAnnotationLink()
{
75 76
  this->Observer->Delete();

77
  if (this->AnnotationLayers)
78
  {
79
    this->AnnotationLayers->Delete();
80
  }
81
  if (this->DomainMaps)
82
  {
83
    this->DomainMaps->Delete();
84
  }
85 86
}

87 88 89 90
//----------------------------------------------------------------------------
void vtkAnnotationLink::ProcessEvents(vtkObject *caller, unsigned long eventId, void *vtkNotUsed(callData))
{
  if(this->AnnotationLayers)
91
  {
92 93
    vtkAnnotationLayers* caller_annotations = vtkAnnotationLayers::SafeDownCast( caller );
    if (caller_annotations == this->AnnotationLayers && eventId == vtkCommand::ModifiedEvent)
94
    {
95
      this->InvokeEvent(vtkCommand::AnnotationChangedEvent, this->AnnotationLayers);
96
    }
97
  }
98 99 100 101 102 103 104 105
}

//----------------------------------------------------------------------------
void vtkAnnotationLink::SetAnnotationLayers(vtkAnnotationLayers* layers)
{
  // This method is a cut and paste of vtkCxxSetObjectMacro
  // except that we listen for modified events from the annotations layers
  if (layers != this->AnnotationLayers)
106
  {
107 108
    vtkAnnotationLayers *tmp = this->AnnotationLayers;
    if (tmp)
109
    {
110
      tmp->RemoveObserver(this->Observer);
111
    }
112
    this->AnnotationLayers = layers;
113
    if (this->AnnotationLayers != nullptr)
114
    {
115
      this->AnnotationLayers->Register(this);
116
      this->AnnotationLayers->AddObserver(vtkCommand::ModifiedEvent,
117
                                        this->Observer);
118
    }
119
    if (tmp != nullptr)
120
    {
121
      tmp->UnRegister(this);
122
    }
123
    this->Modified();
124
    this->InvokeEvent(vtkCommand::AnnotationChangedEvent, this->AnnotationLayers);
125
  }
126 127
}

128 129 130 131
//----------------------------------------------------------------------------
void vtkAnnotationLink::AddDomainMap(vtkTable* map)
{
  if (!this->DomainMaps->IsItemPresent(map))
132
  {
133
    this->DomainMaps->AddItem(map);
134
  }
135 136 137 138 139 140 141 142 143 144 145
}

//----------------------------------------------------------------------------
void vtkAnnotationLink::RemoveDomainMap(vtkTable* map)
{
  this->DomainMaps->RemoveItem(map);
}

//----------------------------------------------------------------------------
void vtkAnnotationLink::RemoveAllDomainMaps()
{
146
  if(this->DomainMaps->GetNumberOfItems() > 0)
147
  {
148
    this->DomainMaps->RemoveAllItems();
149
  }
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
}

//----------------------------------------------------------------------------
int vtkAnnotationLink::GetNumberOfDomainMaps()
{
  return this->DomainMaps->GetNumberOfItems();
}

//----------------------------------------------------------------------------
vtkTable* vtkAnnotationLink::GetDomainMap(int i)
{
  return vtkTable::SafeDownCast(this->DomainMaps->GetItem(i));
}

//----------------------------------------------------------------------------
void vtkAnnotationLink::SetCurrentSelection(vtkSelection* sel)
{
  if (this->AnnotationLayers)
168
  {
169
    this->AnnotationLayers->SetCurrentSelection(sel);
170
  }
171 172 173 174 175 176
}

//----------------------------------------------------------------------------
vtkSelection* vtkAnnotationLink::GetCurrentSelection()
{
  if (this->AnnotationLayers)
177
  {
178
    return this->AnnotationLayers->GetCurrentSelection();
179
  }
180
  return nullptr;
181 182 183 184 185
}

//----------------------------------------------------------------------------
int vtkAnnotationLink::RequestData(
  vtkInformation *vtkNotUsed(info),
186
  vtkInformationVector **inVector,
187 188
  vtkInformationVector *outVector)
{
189
  vtkInformation *inInfo = inVector[0]->GetInformationObject(0);
190
  vtkTable* inputMap = vtkTable::GetData(inVector[1]);
191 192
  vtkAnnotationLayers* input = nullptr;
  vtkSelection* inputSelection = nullptr;
193
  if (inInfo)
194
  {
195
    input = vtkAnnotationLayers::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
196
    inputSelection = vtkSelection::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
197
  }
198

199 200 201
  vtkInformation *outInfo = outVector->GetInformationObject(0);
  vtkAnnotationLayers* output = vtkAnnotationLayers::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));
202

203 204 205
  vtkInformation *mapInfo = outVector->GetInformationObject(1);
  vtkMultiBlockDataSet* maps = vtkMultiBlockDataSet::SafeDownCast(
    mapInfo->Get(vtkDataObject::DATA_OBJECT()));
206

207 208 209
  vtkInformation *selInfo = outVector->GetInformationObject(2);
  vtkSelection* sel = vtkSelection::SafeDownCast(
    selInfo->Get(vtkDataObject::DATA_OBJECT()));
210

211
  // Give preference to input annotations
212
  if (input)
213
  {
214
    this->ShallowCopyToOutput(input, output, sel);
215
  }
216
  else if (this->AnnotationLayers)
217
  {
218
    this->ShallowCopyToOutput(this->AnnotationLayers, output, sel);
219
  }
220

221 222
  // If there is an input selection, set it on the annotation layers
  if (inputSelection)
223
  {
224 225
    sel->ShallowCopy(inputSelection);
    output->SetCurrentSelection(sel);
226
  }
227

228 229
  // If there are input domain maps, give preference to them
  if(inputMap)
230
  {
231 232 233
    vtkSmartPointer<vtkTable> outMap = vtkSmartPointer<vtkTable>::New();
    outMap->ShallowCopy(inputMap);
    maps->SetBlock(0, outMap);
234
  }
235
  else
236
  {
237 238 239
    unsigned int numMaps = static_cast<unsigned int>(this->DomainMaps->GetNumberOfItems());
    maps->SetNumberOfBlocks(numMaps);
    for (unsigned int i = 0; i < numMaps; ++i)
240
    {
241 242 243
      vtkSmartPointer<vtkTable> map = vtkSmartPointer<vtkTable>::New();
      map->ShallowCopy(this->DomainMaps->GetItem(i));
      maps->SetBlock(i, map);
244
    }
245
  }
246

247 248 249
  return 1;
}

250 251 252 253 254 255 256 257 258
//----------------------------------------------------------------------------
void vtkAnnotationLink::ShallowCopyToOutput(
  vtkAnnotationLayers* input,
  vtkAnnotationLayers* output,
  vtkSelection* sel)
{
  output->ShallowCopy(input);

  if (input->GetCurrentSelection())
259
  {
260
    sel->ShallowCopy(input->GetCurrentSelection());
261
  }
262 263 264 265 266 267
}

//----------------------------------------------------------------------------
int vtkAnnotationLink::FillInputPortInformation(int port, vtkInformation* info)
{
  if (port == 0)
268
  {
269
    info->Set(vtkAlgorithm::INPUT_IS_OPTIONAL(), 1);
270 271
    info->Append(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkAnnotationLayers");
    info->Append(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkSelection");
272
    return 1;
273
  }
274
  else if (port == 1)
275
  {
276 277 278 279
    info->Set(vtkAlgorithm::INPUT_IS_OPTIONAL(), 1);
    //info->Set(vtkAlgorithm::INPUT_IS_REPEATABLE(), 1);
    info->Append(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkTable");
    return 1;
280
  }
281 282 283
  return 0;
}

284 285 286 287
//----------------------------------------------------------------------------
int vtkAnnotationLink::FillOutputPortInformation(int port, vtkInformation* info)
{
  if (port == 0)
288
  {
289
    info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkAnnotationLayers");
290
    return 1;
291
  }
292
  else if (port == 1)
293
  {
294
    info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkMultiBlockDataSet");
295
    return 1;
296
  }
297
  else if (port == 2)
298
  {
299
    info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkSelection");
300
    return 1;
301
  }
302
  return 0;
303 304
}

305
//----------------------------------------------------------------------------
306
vtkMTimeType vtkAnnotationLink::GetMTime()
307
{
308
  vtkMTimeType mtime = this->Superclass::GetMTime();
309
  if (this->AnnotationLayers)
310
  {
311
    vtkMTimeType atime = this->AnnotationLayers->GetMTime();
312
    if (atime > mtime)
313
    {
314 315
      mtime = atime;
    }
316
  }
317

318
  if (this->DomainMaps)
319
  {
320
    vtkMTimeType dtime = this->DomainMaps->GetMTime();
321
    if (dtime > mtime)
322
    {
323 324
      mtime = dtime;
    }
325
  }
326

327 328 329
  return mtime;
}

330 331 332 333 334 335
//----------------------------------------------------------------------------
void vtkAnnotationLink::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
  os << indent << "AnnotationLayers: ";
  if (this->AnnotationLayers)
336
  {
337 338
    os << "\n";
    this->AnnotationLayers->PrintSelf(os, indent.GetNextIndent());
339
  }
340
  else
341
  {
342
    os << "(none)\n";
343
  }
344 345
  os << indent << "DomainMaps: ";
  if (this->DomainMaps)
346
  {
347 348
    os << "\n";
    this->DomainMaps->PrintSelf(os, indent.GetNextIndent());
349
  }
350
  else
351
  {
352
    os << "(none)\n";
353
  }
354 355
}