vtkAlgorithm.cxx 24.3 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*=========================================================================

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

#include "vtkAlgorithmOutput.h"
Ken Martin's avatar
Ken Martin committed
18
#include "vtkCommand.h"
19
#include "vtkGarbageCollector.h"
20
#include "vtkInformation.h"
21
22
23
#include "vtkInformationInformationVectorKey.h"
#include "vtkInformationIntegerKey.h"
#include "vtkInformationStringKey.h"
24
25
26
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkSmartPointer.h"
27
#include "vtkStreamingDemandDrivenPipeline.h"
28
29
30
31

#include <vtkstd/set>
#include <vtkstd/vector>

32
vtkCxxRevisionMacro(vtkAlgorithm, "1.18");
33
34
vtkStandardNewMacro(vtkAlgorithm);

35
36
vtkCxxSetObjectMacro(vtkAlgorithm,Information,vtkInformation);

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//----------------------------------------------------------------------------
class vtkAlgorithmInternals
{
public:
  // The executive currently managing this algorithm.
  vtkSmartPointer<vtkExecutive> Executive;

  // Connections are stored at each end by pointing at the algorithm
  // and input/output port index of the other end of the connection.
  struct PortEntry
  {
    vtkSmartPointer< vtkAlgorithm > Algorithm;
    int PortIndex;
  };

  // An output port may be connected to zero or more consumers.  An
  // input port may be connected to zero or more producers.
  struct Port: public vtkstd::vector<PortEntry>
  {
    iterator Find(vtkAlgorithm* algorithm, int portIndex)
      {
      for(iterator i = begin(); i != end(); ++i)
        {
        if(i->Algorithm == algorithm && i->PortIndex == portIndex)
          {
          return i;
          }
        }
      return this->end();
      }
    void Insert(vtkAlgorithm* algorithm, int portIndex)
      {
69
70
71
      this->resize(this->size()+1);
      (end()-1)->Algorithm = algorithm;
      (end()-1)->PortIndex = portIndex;
72
73
74
75
76
      }
    void Remove(vtkAlgorithm* algorithm, int portIndex)
      {
      this->erase(this->Find(algorithm, portIndex));
      }
77
78

    vtkSmartPointer<vtkInformation> Information;
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
  };

  // Each algorithm has zero or more input ports and zero or more
  // output ports.
  vtkstd::vector<Port> InputPorts;
  vtkstd::vector<Port> OutputPorts;

  // Proxy object instances for use in establishing connections from
  // the output ports to other algorithms.
  vtkstd::vector< vtkSmartPointer<vtkAlgorithmOutput> > Outputs;
};

static void vtkAlgorithmIgnoreUnused(void*) {}

//----------------------------------------------------------------------------
class vtkAlgorithmToExecutiveFriendship
{
public:
  static void AddAlgorithm(vtkExecutive* executive, vtkAlgorithm* algorithm)
    {
    executive->AddAlgorithm(algorithm);
    }
  static void RemoveAlgorithm(vtkExecutive* executive, vtkAlgorithm* algorithm)
    {
    executive->RemoveAlgorithm(algorithm);
    }
};

//----------------------------------------------------------------------------
void vtkAlgorithm::ConnectionAdd(vtkAlgorithm* producer, int producerPort,
                                 vtkAlgorithm* consumer, int consumerPort)
{
  // Add the consumer's reference to the producer.
  consumer->AlgorithmInternal
    ->InputPorts[consumerPort].Insert(producer, producerPort);

  // Add the producer's reference to the consumer.
  producer->AlgorithmInternal
    ->OutputPorts[producerPort].Insert(consumer, consumerPort);
}

//----------------------------------------------------------------------------
void vtkAlgorithm::ConnectionRemove(vtkAlgorithm* producer, int producerPort,
                                    vtkAlgorithm* consumer, int consumerPort)
{
  // Remove the consumer's reference to the producer.
  consumer->AlgorithmInternal
    ->InputPorts[consumerPort].Remove(producer, producerPort);

  // Remove the producer's reference to the consumer.
  producer->AlgorithmInternal
    ->OutputPorts[producerPort].Remove(consumer, consumerPort);
}

//----------------------------------------------------------------------------
void vtkAlgorithm::ConnectionRemoveAllInput(vtkAlgorithm* consumer, int port)
{
  vtkAlgorithmInternals::Port& inputPort =
    consumer->AlgorithmInternal->InputPorts[port];

  // Remove all producers' references to this consumer.
  for(vtkAlgorithmInternals::Port::iterator i = inputPort.begin();
      i != inputPort.end(); ++i)
    {
    i->Algorithm->AlgorithmInternal
      ->OutputPorts[i->PortIndex].Remove(consumer, port);
    }

  // Remove this consumer's references to all producers.
  inputPort.clear();
}

//----------------------------------------------------------------------------
void vtkAlgorithm::ConnectionRemoveAllOutput(vtkAlgorithm* producer, int port)
{
  vtkAlgorithmInternals::Port& outputPort =
    producer->AlgorithmInternal->OutputPorts[port];

  // Remove all consumers' references to this producer.
  for(vtkAlgorithmInternals::Port::iterator i = outputPort.begin();
      i != outputPort.end(); ++i)
    {
    i->Algorithm->AlgorithmInternal
      ->InputPorts[i->PortIndex].Remove(producer, port);
    }

  // Remove this producer's references to all consumers.
  outputPort.clear();
}

//----------------------------------------------------------------------------
vtkAlgorithm::vtkAlgorithm()
{
Ken Martin's avatar
Ken Martin committed
172
173
174
  this->AbortExecute = 0;
  this->Progress = 0.0;
  this->ProgressText = NULL;
175
176
  this->AlgorithmInternal = new vtkAlgorithmInternals;
  this->GarbageCollecting = 0;
177
  this->Information = vtkInformation::New();
178
179
180
181
182
}

//----------------------------------------------------------------------------
vtkAlgorithm::~vtkAlgorithm()
{
183
  this->SetInformation(0);
184
  delete this->AlgorithmInternal;
Ken Martin's avatar
Ken Martin committed
185
186
  delete [] this->ProgressText;
  this->ProgressText = NULL;
187
188
}

Ken Martin's avatar
Ken Martin committed
189
190
191
192
193
194
195
196
197
198
// Update the progress of the process object. If a ProgressMethod exists,
// executes it. Then set the Progress ivar to amount. The parameter amount
// should range between (0,1).
void vtkAlgorithm::UpdateProgress(double amount)
{
  this->Progress = amount;
  this->InvokeEvent(vtkCommand::ProgressEvent,(void *)&amount);
}


199
200
201
202
203
204
205
206
207
208
209
210
211
//----------------------------------------------------------------------------
void vtkAlgorithm::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  if(this->HasExecutive())
    {
    os << indent << "Executive: "
       << this->AlgorithmInternal->Executive.GetPointer() << "\n";
    }
  else
    {
    os << indent << "Executive: (none)\n";
    }
Ken Martin's avatar
Ken Martin committed
212

213
214
215
216
217
218
219
220
221
  if ( this->Information )
    {
    os << indent << "Information: " << this->Information << "\n";
    }
  else
    {
    os << indent << "Information: (none)\n";
    }

Ken Martin's avatar
Ken Martin committed
222
223
224
225
226
227
228
229
230
231
  os << indent << "AbortExecute: " << (this->AbortExecute ? "On\n" : "Off\n");
  os << indent << "Progress: " << this->Progress << "\n";
  if ( this->ProgressText )
    {
    os << indent << "Progress Text: " << this->ProgressText << "\n";
    }
  else
    {
    os << indent << "Progress Text: (None)\n";
    }
232
233
234
235
236
237
238
239
240
241
242
243
244
245
}

//----------------------------------------------------------------------------
int vtkAlgorithm::HasExecutive()
{
  return this->AlgorithmInternal->Executive.GetPointer()? 1:0;
}

//----------------------------------------------------------------------------
vtkExecutive* vtkAlgorithm::GetExecutive()
{
  // Create the default executive if we do not have one already.
  if(!this->HasExecutive())
    {
246
    vtkExecutive* e = this->CreateDefaultExecutive();
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
    this->SetExecutive(e);
    e->Delete();
    }
  return this->AlgorithmInternal->Executive.GetPointer();
}

//----------------------------------------------------------------------------
void vtkAlgorithm::SetExecutive(vtkExecutive* executive)
{
  if(vtkExecutive* oldExecutive =
     this->AlgorithmInternal->Executive.GetPointer())
    {
    // If this algorithm is already managed by the executive, do
    // nothing.
    if(executive == oldExecutive)
      {
      return;
      }

    // The old executive is no longer managing this algorithm.
    vtkAlgorithmToExecutiveFriendship::RemoveAlgorithm(oldExecutive, this);
    }

  // The given executive now manages this algorithm.
  this->AlgorithmInternal->Executive = executive;
  if(executive)
    {
    vtkAlgorithmToExecutiveFriendship::AddAlgorithm(executive, this);
    }
}

//----------------------------------------------------------------------------
279
280
int vtkAlgorithm::ProcessUpstreamRequest(vtkInformation*,
                                         vtkInformationVector* inVector,
281
282
283
284
285
286
287
288
289
290
291
292
                                         vtkInformationVector* outVector)
{
  if(!inVector)
    {
    vtkErrorMacro("ProcessUpstreamRequest called with NULL input vector.");
    return 0;
    }
  if(!outVector)
    {
    vtkErrorMacro("ProcessUpstreamRequest called with NULL output vector.");
    return 0;
    }
293
  return 1;
294
295
296
}

//----------------------------------------------------------------------------
297
298
int vtkAlgorithm::ProcessDownstreamRequest(vtkInformation*,
                                           vtkInformationVector* inVector,
299
300
301
302
303
304
305
306
307
308
309
310
                                           vtkInformationVector* outVector)
{
  if(!inVector)
    {
    vtkErrorMacro("ProcessDownstreamRequest called with NULL input vector.");
    return 0;
    }
  if(!outVector)
    {
    vtkErrorMacro("ProcessDownstreamRequest called with NULL output vector.");
    return 0;
    }
311
  return 1;
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
}

//----------------------------------------------------------------------------
int vtkAlgorithm::GetNumberOfInputPorts()
{
  return static_cast<int>(this->AlgorithmInternal->InputPorts.size());
}

//----------------------------------------------------------------------------
void vtkAlgorithm::SetNumberOfInputPorts(int n)
{
  // Sanity check.
  if(n < 0)
    {
    vtkErrorMacro("Attempt to set number of input ports to " << n);
    n = 0;
    }

  // We must remove all connections from ports that are removed.
  for(int i=n; i < this->GetNumberOfInputPorts(); ++i)
    {
    vtkAlgorithm::ConnectionRemoveAllInput(this, i);
    }
  this->AlgorithmInternal->InputPorts.resize(n);
}

//----------------------------------------------------------------------------
int vtkAlgorithm::GetNumberOfOutputPorts()
{
  return static_cast<int>(this->AlgorithmInternal->OutputPorts.size());
}

//----------------------------------------------------------------------------
void vtkAlgorithm::SetNumberOfOutputPorts(int n)
{
  // Sanity check.
  if(n < 0)
    {
    vtkErrorMacro("Attempt to set number of output ports to " << n);
    n = 0;
    }

  // We must remove all connections from ports that are removed.
  for(int i=n; i < this->GetNumberOfOutputPorts(); ++i)
    {
    vtkAlgorithm::ConnectionRemoveAllOutput(this, i);
    }
  this->AlgorithmInternal->OutputPorts.resize(n);
  this->AlgorithmInternal->Outputs.resize(n);
}

//----------------------------------------------------------------------------
void vtkAlgorithm::SetInput(int index, vtkAlgorithmOutput* input)
{
  this->SetInputConnection(index, input);
}

//----------------------------------------------------------------------------
370
vtkDataObject* vtkAlgorithm::GetOutputDataObject(int port)
371
{
372
373
374
375
376
  if(!this->OutputPortIndexInRange(port, "get the data object for"))
    {
    return 0;
    }
  return this->GetExecutive()->GetOutputData(this, port);
377
378
379
}

//----------------------------------------------------------------------------
380
void vtkAlgorithm::SetInputConnection(int port, vtkAlgorithmOutput* input)
381
{
382
  if(!this->InputPortIndexInRange(port, "connect"))
383
384
385
386
387
388
    {
    return;
    }

  // Check if the connection is already present.
  if(input &&
389
390
391
392
     this->AlgorithmInternal->InputPorts[port].size() == 1 &&
     this->AlgorithmInternal->InputPorts[port].Find(input->GetProducer(),
                                                    input->GetIndex()) !=
     this->AlgorithmInternal->InputPorts[port].end())
393
394
395
396
    {
    // The connection is the only one present.  No change is needed.
    return;
    }
397
  else if(!input && this->AlgorithmInternal->InputPorts[port].empty())
398
399
400
401
402
403
404
405
406
407
408
409
410
411
    {
    // New connection is NULL and there are no connections to remove.
    return;
    }

  // Hold an extra reference to this object and the producer of the
  // new input in case an existing connection is the only reference to
  // either.
  vtkSmartPointer<vtkAlgorithm> consumer = this;
  vtkSmartPointer<vtkAlgorithm> producer = input?input->GetProducer():0;
  vtkAlgorithmIgnoreUnused(&consumer);
  vtkAlgorithmIgnoreUnused(&producer);

  // Remove all other connections.
412
  if(!this->AlgorithmInternal->InputPorts[port].empty())
413
    {
414
    vtkDebugMacro("Removing all connections to input port " << port << ".");
415
    vtkAlgorithm::ConnectionRemoveAllInput(this, port);
416
417
418
419
420
    }

  // Add the new connection.
  if(input)
    {
421
422
423
424
425
426
    vtkDebugMacro("Adding connection from output port index "
                  << input->GetIndex() << " on algorithm "
                  << (input->GetProducer()?
                      input->GetProducer()->GetClassName() : "NULL")
                  << "(" << input->GetProducer() << ") to input port "
                  << port << ".");
427
    vtkAlgorithm::ConnectionAdd(input->GetProducer(), input->GetIndex(),
428
                                this, port);
429
430
431
432
433
    }
  this->Modified();
}

//----------------------------------------------------------------------------
434
void vtkAlgorithm::AddInputConnection(int port, vtkAlgorithmOutput* input)
435
{
436
  if(!this->InputPortIndexInRange(port, "connect"))
437
438
439
440
441
    {
    return;
    }

  // Add the new connection.
442
443
444
445
446
447
  vtkDebugMacro("Adding connection from output port index "
                << input->GetIndex() << " on algorithm "
                << (input->GetProducer()?
                    input->GetProducer()->GetClassName() : "NULL")
                << "(" << input->GetProducer() << ") to input port "
                << port << ".");
448
  vtkAlgorithm::ConnectionAdd(input->GetProducer(), input->GetIndex(),
449
                              this, port);
450
451
452
453
  this->Modified();
}

//----------------------------------------------------------------------------
454
void vtkAlgorithm::RemoveInputConnection(int port, vtkAlgorithmOutput* input)
455
{
456
  if(!this->InputPortIndexInRange(port, "disconnect"))
457
458
459
460
461
462
    {
    return;
    }

  // Check if the connection is present.
  if(!input ||
463
464
465
     this->AlgorithmInternal->InputPorts[port].Find(input->GetProducer(),
                                                    input->GetIndex()) ==
     this->AlgorithmInternal->InputPorts[port].end())
466
467
468
469
470
    {
    return;
    }

  // Remove the connection.
471
472
473
474
475
476
  vtkDebugMacro("Removing connection from output port index "
                << input->GetIndex() << " on algorithm "
                << (input->GetProducer()?
                    input->GetProducer()->GetClassName() : "NULL")
                << "(" << input->GetProducer() << ") to input port "
                << port << ".");
477
  vtkAlgorithm::ConnectionRemove(input->GetProducer(), input->GetIndex(),
478
                                 this, port);
479
480
481
482
  this->Modified();
}

//----------------------------------------------------------------------------
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
void vtkAlgorithm::SetNthInputConnection(int port, int index,
                                         vtkAlgorithmOutput* input)
{
  if(!this->InputPortIndexInRange(port, "replace connection"))
    {
    return;
    }

  // Check if the connection index exists.
  if(!input || index < 0 || index >= this->GetNumberOfInputConnections(port))
    {
    return;
    }

  // Add the new connection.
  int oldNumberOfConnections = this->GetNumberOfInputConnections(port);
  this->AddInputConnection(port, input);
  if(this->GetNumberOfInputConnections(port) > oldNumberOfConnections)
    {
    // The connection was really added.  Swap it into the correct
    // connection index.
    vtkAlgorithmInternals::PortEntry temp =
      this->AlgorithmInternal->InputPorts[port][index];
    this->AlgorithmInternal->InputPorts[port][index] =
      this->AlgorithmInternal->InputPorts[port][oldNumberOfConnections];
    this->AlgorithmInternal->InputPorts[port][oldNumberOfConnections] = temp;

    // Now remove the connection that was previously at this index.
    this->RemoveInputConnection(port,
                                temp.Algorithm->GetOutputPort(temp.PortIndex));
    }
  else
    {
    // The connection was already present.
    vtkErrorMacro("SetNthInputConnection cannot duplicate another input.");
    }
}

//----------------------------------------------------------------------------
vtkAlgorithmOutput* vtkAlgorithm::GetOutputPort(int port)
523
{
524
  if(!this->OutputPortIndexInRange(port, "get"))
525
526
527
528
529
    {
    return 0;
    }

  // Create the vtkAlgorithmOutput proxy object if there is not one.
530
  if(!this->AlgorithmInternal->Outputs[port].GetPointer())
531
532
533
    {
    vtkAlgorithmOutput* output = vtkAlgorithmOutput::New();
    output->SetProducer(this);
534
535
    output->SetIndex(port);
    this->AlgorithmInternal->Outputs[port] = output;
536
537
538
539
    output->Delete();
    }

  // Return the proxy object instance.
540
  return this->AlgorithmInternal->Outputs[port].GetPointer();
541
542
543
}

//----------------------------------------------------------------------------
544
vtkInformation* vtkAlgorithm::GetInputPortInformation(int port)
545
{
546
  if(!this->InputPortIndexInRange(port, "get information object for"))
547
    {
548
549
550
551
552
553
554
    return 0;
    }
  if(!this->AlgorithmInternal->InputPorts[port].Information.GetPointer())
    {
    vtkInformation* info = vtkInformation::New();
    if(!this->FillInputPortInformation(port, info))
      {
555
      info->Clear();
556
557
558
      }
    this->AlgorithmInternal->InputPorts[port].Information = info;
    info->Delete();
559
    }
560
  return this->AlgorithmInternal->InputPorts[port].Information.GetPointer();
561
562
563
}

//----------------------------------------------------------------------------
564
vtkInformation* vtkAlgorithm::GetOutputPortInformation(int port)
565
{
566
  if(!this->OutputPortIndexInRange(port, "get information object for"))
567
    {
568
    return 0;
569
    }
570
571
572
573
574
  if(!this->AlgorithmInternal->OutputPorts[port].Information.GetPointer())
    {
    vtkInformation* info = vtkInformation::New();
    if(!this->FillOutputPortInformation(port, info))
      {
575
      info->Clear();
576
577
578
579
580
      }
    this->AlgorithmInternal->OutputPorts[port].Information = info;
    info->Delete();
    }
  return this->AlgorithmInternal->OutputPorts[port].Information.GetPointer();
581
582
583
}

//----------------------------------------------------------------------------
584
int vtkAlgorithm::FillInputPortInformation(int, vtkInformation*)
585
{
586
  vtkErrorMacro("FillInputPortInformation is not implemented.");
587
  return 0;
588
589
590
}

//----------------------------------------------------------------------------
591
int vtkAlgorithm::FillOutputPortInformation(int, vtkInformation*)
592
{
593
  vtkErrorMacro("FillOutputPortInformation is not implemented.");
594
  return 0;
595
596
}

597
598
599
600
601
602
603
604
605
606
607
608
609
//----------------------------------------------------------------------------
int vtkAlgorithm::GetNumberOfInputConnections(int port)
{
  if(!this->InputPortIndexInRange(port, "get number of connections for"))
    {
    return 0;
    }
  return static_cast<int>(this->AlgorithmInternal->InputPorts[port].size());
}

//----------------------------------------------------------------------------
vtkAlgorithmOutput* vtkAlgorithm::GetInputConnection(int port, int index)
{
610
  if(!this->InputPortIndexInRange(port, "get number of connections for"))
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
    {
    return 0;
    }
  if(index < 0 || index >= this->GetNumberOfInputConnections(port))
    {
    vtkErrorMacro("Attempt to get connection index " << index
                  << " for input port " << port << ", which has "
                  << this->GetNumberOfInputConnections(port)
                  << " connections.");
    return 0;
    }
  vtkAlgorithmInternals::Port& inputPort =
    this->AlgorithmInternal->InputPorts[port];
  return inputPort[index].Algorithm->GetOutputPort(inputPort[index].PortIndex);
}

//----------------------------------------------------------------------------
int vtkAlgorithm::InputPortIndexInRange(int index, const char* action)
{
  // Make sure the index of the input port is in range.
  if(index < 0 || index >= this->GetNumberOfInputPorts())
    {
    vtkErrorMacro("Attempt to " << (action?action:"access")
                  << " input port index " << index
                  << " for an algorithm with "
                  << this->GetNumberOfInputPorts() << " input ports.");
    return 0;
    }
  return 1;
}

//----------------------------------------------------------------------------
int vtkAlgorithm::OutputPortIndexInRange(int index, const char* action)
{
  // Make sure the index of the output port is in range.
  if(index < 0 || index >= this->GetNumberOfOutputPorts())
    {
    vtkErrorMacro("Attempt to " << (action?action:"access")
                  << " output port index " << index
                  << " for an algorithm with "
                  << this->GetNumberOfOutputPorts() << " output ports.");
    return 0;
    }
  return 1;
}

657
658
659
660
661
662
//----------------------------------------------------------------------------
void vtkAlgorithm::Update()
{
  this->GetExecutive()->Update(this);
}

Ken Martin's avatar
Ken Martin committed
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
//----------------------------------------------------------------------------
void vtkAlgorithm::UpdateWholeExtent()
{
  vtkStreamingDemandDrivenPipeline* sddp =
    vtkStreamingDemandDrivenPipeline::SafeDownCast(this->GetExecutive());
  if (sddp)
    {
    sddp->UpdateWholeExtent(this);
    }
  else
    {
    this->Update();
    }
}

678
679
680
//----------------------------------------------------------------------------
vtkExecutive* vtkAlgorithm::CreateDefaultExecutive()
{
681
  return vtkStreamingDemandDrivenPipeline::New();
682
683
}

684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
//----------------------------------------------------------------------------
void vtkAlgorithm::UnRegister(vtkObjectBase* o)
{
  int check = (this->GetReferenceCount() > 1);
  this->Superclass::UnRegister(o);
  if(check && !this->GarbageCollecting)
    {
    vtkGarbageCollector::Check(this);
    }
}

//----------------------------------------------------------------------------
void vtkAlgorithm::ReportReferences(vtkGarbageCollector* collector)
{
  this->Superclass::ReportReferences(collector);
699
700
  collector->ReportReference(this->AlgorithmInternal->Executive.GetPointer(),
                             "Executive");
701
702
703
704
705
706
707
708
709
  vtkstd::vector<vtkAlgorithmInternals::Port>::iterator i;

  // Report producers.
  for(i = this->AlgorithmInternal->InputPorts.begin();
      i != this->AlgorithmInternal->InputPorts.end(); ++i)
    {
    for(vtkAlgorithmInternals::Port::iterator j = i->begin();
        j != i->end(); ++j)
      {
710
      collector->ReportReference(j->Algorithm.GetPointer(), "InputPorts");
711
712
713
714
715
716
717
718
719
720
      }
    }

  // Report consumers.
  for(i = this->AlgorithmInternal->OutputPorts.begin();
      i != this->AlgorithmInternal->OutputPorts.end(); ++i)
    {
    for(vtkAlgorithmInternals::Port::iterator j = i->begin();
        j != i->end(); ++j)
      {
721
      collector->ReportReference(j->Algorithm.GetPointer(), "OutputPorts");
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
      }
    }
}

//----------------------------------------------------------------------------
void vtkAlgorithm::GarbageCollectionStarting()
{
  this->GarbageCollecting = 1;
  this->Superclass::GarbageCollectionStarting();
}

//----------------------------------------------------------------------------
void vtkAlgorithm::RemoveReferences()
{
  this->AlgorithmInternal->Executive = 0;
737
738
739
740
741
742
743
744
745
746
747
748
749

  // Remove all connection-related references without clearing the ports
  // array.  The destructor of a subclass may still need to access the number
  // of input or output ports.
  int i;
  for(i=0; i < this->GetNumberOfInputPorts(); ++i)
    {
    this->AlgorithmInternal->InputPorts[i].clear();
    }
  for(i=0; i < this->GetNumberOfOutputPorts(); ++i)
    {
    this->AlgorithmInternal->OutputPorts[i].clear();
    }
750
751
  this->Superclass::RemoveReferences();
}
752
753
754
755
756
757
758
759
760
761
762
763
764
765

//----------------------------------------------------------------------------
// Define information keys for algorithms.
#define VTK_ALGORITHM_DEFINE_KEY_METHOD(NAME, type)                         \
  vtkInformation##type##Key* vtkAlgorithm::NAME()                           \
    {                                                                       \
    static vtkInformation##type##Key instance(#NAME, "vtkAlgorithm");       \
    return &instance;                                                       \
    }
VTK_ALGORITHM_DEFINE_KEY_METHOD(INPUT_REQUIRED_DATA_TYPE, String);
VTK_ALGORITHM_DEFINE_KEY_METHOD(INPUT_IS_OPTIONAL, Integer);
VTK_ALGORITHM_DEFINE_KEY_METHOD(INPUT_IS_REPEATABLE, Integer);
VTK_ALGORITHM_DEFINE_KEY_METHOD(INPUT_CONNECTION_INFORMATION, InformationVector);
VTK_ALGORITHM_DEFINE_KEY_METHOD(INPUT_REQUIRED_FIELDS, InformationVector);