Orfeo Toolbox  4.0
itkProcessObject.cxx
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 /*=========================================================================
19  *
20  * Portions of this file are subject to the VTK Toolkit Version 3 copyright.
21  *
22  * Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
23  *
24  * For complete copyright, license and disclaimer of warranty information
25  * please refer to the NOTICE file at the top of the ITK source tree.
26  *
27  *=========================================================================*/
28 #include "itkProcessObject.h"
29 #include "itkMutexLockHolder.h"
30 
31 #include <stdio.h>
32 #include <sstream>
33 #include <algorithm>
34 
35 namespace itk
36 {
37 
38 
39 namespace
40 { // local namespace for managing globals
41 const size_t ITK_GLOBAL_INDEX_NAMES_NUMBER = 100;
42 const size_t ITK_GLOBAL_INDEX_NAMES_LENGTH = 4;
43 const char globalIndexNames[ITK_GLOBAL_INDEX_NAMES_NUMBER][ITK_GLOBAL_INDEX_NAMES_LENGTH] =
44 { "_0", "_1", "_2", "_3", "_4", "_5", "_6", "_7", "_8", "_9",
45  "_10", "_11", "_12", "_13", "_14", "_15", "_16", "_17", "_18", "_19",
46  "_20", "_21", "_22", "_23", "_24", "_25", "_26", "_27", "_28", "_29",
47  "_30", "_31", "_32", "_33", "_34", "_35", "_36", "_37", "_38", "_39",
48  "_40", "_41", "_42", "_43", "_44", "_45", "_46", "_47", "_48", "_49",
49  "_50", "_51", "_52", "_53", "_54", "_55", "_56", "_57", "_58", "_59",
50  "_60", "_61", "_62", "_63", "_64", "_65", "_66", "_67", "_68", "_69",
51  "_70", "_71", "_72", "_73", "_74", "_75", "_76", "_77", "_78", "_79",
52  "_80", "_81", "_82", "_83", "_84", "_85", "_86", "_87", "_88", "_89",
53  "_90", "_91", "_92", "_93", "_94", "_95", "_96", "_97", "_98", "_99"
54 };
55 
56 }
57 
58 
64  m_Inputs(),
65  m_Outputs(),
66  m_CachedInputReleaseDataFlags(),
67  m_RequiredInputNames()
68 {
69  m_NumberOfRequiredInputs = 0;
70  m_NumberOfRequiredOutputs = 0;
71 
72  m_AbortGenerateData = false;
73  m_Progress = 0.0f;
74  m_Updating = false;
75 
76  DataObjectPointerMap::value_type p("Primary", DataObjectPointer() );
77  m_IndexedInputs.push_back( m_Inputs.insert(p).first );
78  m_IndexedOutputs.push_back( m_Outputs.insert(p).first );
79 
80  m_Threader = MultiThreader::New();
81  m_NumberOfThreads = m_Threader->GetNumberOfThreads();
82 
83  m_ReleaseDataBeforeUpdateFlag = true;
84 
85 }
86 
96 {
97  itkDebugMacro("MakeOutput(" << name << ")");
98  if( this->IsIndexedOutputName(name) )
99  {
100  return this->MakeOutput( this->MakeIndexFromOutputName(name) );
101  }
102  return static_cast<DataObject *>(DataObject::New().GetPointer());
103 }
104 
108 {
109  return static_cast<DataObject *>(DataObject::New().GetPointer());
110 }
111 
112 
119 {
120  // Tell each output that we are going away. If other objects have a
121  // reference to one of these outputs, the data object will not be deleted
122  // when the process object is deleted. However, the data object's source
123  // will still point back to the now nonexistent process object if we do not
124  // clean things up now.
125  for ( DataObjectPointerMap::iterator it = m_Outputs.begin(); it != m_Outputs.end(); ++it )
126  {
127  if ( it->second )
128  {
129  // let the output know we no longer want to associate with the object
130  it->second->DisconnectSource(this, it->first);
131  // let go of our reference to the data object
132  it->second = 0;
133  }
134  }
135 }
136 
140 void
143 {
144  if( this->GetNumberOfIndexedInputs() != num )
145  {
146  if ( num < this->GetNumberOfIndexedInputs() )
147  {
148  // NB: The primary input must never be removed from the map, or
149  // the indexed inputs array!
150 
151  // remove the extra inputs
152  for( DataObjectPointerArraySizeType i=std::max<DataObjectPointerArraySizeType>(num, 1);
153  i<this->GetNumberOfIndexedInputs(); ++i )
154  {
155  m_Inputs.erase( m_IndexedInputs[i]->first );
156  }
157  m_IndexedInputs.resize(std::max<DataObjectPointerArraySizeType>(num, 1) );
158 
159 
160  if (num < 1 )
161  {
162  m_IndexedInputs[0]->second = NULL;
163  }
164  }
165  else
166  {
167  for ( DataObjectPointerArraySizeType i = m_IndexedInputs.size(); i < num; ++i)
168  {
169  DataObjectPointerMap::value_type p(this->MakeNameFromInputIndex( i ), DataObjectPointer() );
170  // note: insert will not change value if it's already there.
171  m_IndexedInputs.push_back ( m_Inputs.insert(p).first );
172  }
173  }
174 
175  this->Modified();
176  }
177 }
178 
185 {
187  for( DataObjectPointerArraySizeType i = 0; i < m_NumberOfRequiredInputs; i++ )
188  {
189  if( this->GetInput( i ) )
190  {
191  ++count;
192  }
193  }
194  return count;
195 }
196 
201 void
204 {
205  for ( unsigned idx = 0; idx < this->GetNumberOfIndexedInputs(); ++idx )
206  {
207  if ( !this->GetInput( idx ) )
208  {
209  this->SetNthInput( idx, input );
210  return;
211  }
212  }
213  this->SetNthInput( this->GetNumberOfIndexedInputs(), input );
214 }
215 
219 void
222 {
223 
224  // if primary or required set to null
225  if ( key == m_IndexedInputs[0]->first || this->IsRequiredInputName(key) )
226  {
227  this->SetInput(key, NULL);
228  return;
229  }
230 
231  // set indexed input to null, remove if last
232  for ( DataObjectPointerArraySizeType i = 1; i < m_IndexedInputs.size(); ++i )
233  {
234  if ( m_IndexedInputs[i]->first == key )
235  {
236  this->SetNthInput(i, NULL);
237  if ( i == m_IndexedInputs.size() - 1 )
238  {
239  // remove the last indexed input
240  this->SetNumberOfIndexedInputs( this->GetNumberOfIndexedInputs() -1 );
241  }
242  return;
243  }
244  }
245 
246  DataObjectPointerMap::iterator it = m_Inputs.find(key);
247 
248  if ( it != m_Inputs.end() )
249  {
250  m_Inputs.erase( it );
251  this->Modified();
252  }
253 }
254 
255 
260 void
263 {
264  if( idx < this->GetNumberOfIndexedInputs() )
265  {
266  this->RemoveInput( m_IndexedInputs[idx]->first );
267  }
268  else
269  {
270  this->RemoveInput( this->MakeNameFromInputIndex( idx ) );
271  }
272 }
273 
277 void
280 {
281  if( key.empty() )
282  {
283  itkExceptionMacro("An empty string can't be used as an input identifier");
284  }
285  DataObjectPointerMap::iterator it = m_Inputs.find(key);
286  if( it == m_Inputs.end() )
287  {
288  // this is a whole new entry
289  m_Inputs[key] = input;
290  this->Modified();
291  }
292  else if( it->second.GetPointer() != input )
293  {
294  // there is already an entry, but not with the right object
295  it->second = input;
296  this->Modified();
297  }
298  // the entry is already there - there is nothing to do
299 }
300 
306 void
309 {
310  if ( idx >= this->GetNumberOfIndexedInputs() )
311  {
312  this->SetNumberOfIndexedInputs(idx + 1);
313  }
314  if ( m_IndexedInputs[idx]->second != input )
315  {
316  m_IndexedInputs[idx]->second = input;
317  this->Modified();
318  }
319 }
320 
324 void
327 {
328  this->SetNthInput( this->GetNumberOfIndexedInputs(), const_cast< DataObject * >( input ) );
329 }
330 
334 void
337 {
338  if ( this->GetNumberOfIndexedInputs() > 0 )
339  {
340  this->SetNumberOfIndexedInputs( this->GetNumberOfIndexedInputs() - 1 );
341  }
342 }
343 
347 void
350 {
351  const DataObjectPointerArraySizeType nb = this->GetNumberOfIndexedInputs();
352  for( DataObjectPointerArraySizeType i = nb; i > 0; i-- )
353  {
354  this->SetNthInput( i, this->GetInput(i-1) );
355  }
356  this->SetNthInput( 0, const_cast< DataObject * >( input ) );
357 }
358 
362 void
365 {
366  DataObjectPointerArraySizeType nb = this->GetNumberOfIndexedInputs();
367  if( nb > 0 )
368  {
369  for( DataObjectPointerArraySizeType i = 1; i < nb; i++ )
370  {
371  this->SetNthInput( i-1, this->GetInput( i ) );
372  }
373  this->SetNumberOfIndexedInputs( nb - 1 );
374  }
375 }
376 
381 void
384 {
385  // if primary or required set to null
386  if ( key == m_IndexedOutputs[0]->first )
387  {
388  this->SetOutput( key, NULL );
389  return;
390  }
391 
392  // set indexed output to null, remove if last
393  for ( DataObjectPointerArraySizeType i = 1; i < m_IndexedOutputs.size(); ++i )
394  {
395  if ( m_IndexedOutputs[i]->first == key )
396  {
397  this->SetNthOutput(i, NULL);
398  if ( i == m_IndexedOutputs.size() - 1 )
399  {
400  // remove the last indexed input
401  this->SetNumberOfIndexedOutputs( this->GetNumberOfIndexedOutputs() -1 );
402  }
403  return;
404  }
405  }
406 
407 
408  DataObjectPointerMap::iterator it = m_Outputs.find(key);
409 
410  if ( it != m_Outputs.end() )
411  {
412  // let the output know we no longer want to associate with the object
413  it->second->DisconnectSource( this, it->first );
414  m_Outputs.erase( it );
415  // let go of our reference to the data object
416  this->Modified();
417  }
418 }
419 
420 void
423 {
424  if( idx == this->GetNumberOfIndexedOutputs() - 1 )
425  {
426  // just remove the last indexed output
427  this->SetNumberOfIndexedOutputs( this->GetNumberOfIndexedOutputs() -1 );
428  }
429  else
430  {
431  this->RemoveOutput( this->MakeNameFromOutputIndex( idx ) );
432  }
433 }
434 
441 void
444 {
445  // copy the key, because it might be destroyed in that method, so a reference
446  // is not enough.
447  DataObjectIdentifierType key = name;
448 
449  if( key.empty() )
450  {
451  itkExceptionMacro("An empty string can't be used as an output identifier");
452  }
453 
454  // does this change anything?
455  DataObjectPointerMap::const_iterator it = m_Outputs.find(key);
456  if ( it != m_Outputs.end() && it->second.GetPointer() == output)
457  {
458  return;
459  }
460 
461  // Keep a handle to the original output and disconnect the old output from
462  // the pipeline
463  DataObjectPointer oldOutput;
464  if ( m_Outputs[key] )
465  {
466  oldOutput = m_Outputs[key];
467  m_Outputs[key]->DisconnectSource(this, key);
468  }
469 
470  if ( output )
471  {
472  output->ConnectSource(this, key);
473  }
474  // save the current reference (which releases the previous reference)
475  m_Outputs[key] = output;
476 
477  // if we are clearing an output, we need to create a new blank output
478  // so we are prepared for the next Update(). this copies the requested
479  // region ivar
480  if ( !m_Outputs[key] )
481  {
482  itkDebugMacro(" creating new output object.");
483  DataObjectPointer newOutput = this->MakeOutput(key);
484  this->SetOutput(key, newOutput);
485 
486  // If we had an output object before, copy the requested region
487  // ivars and release data flag to the the new output
488  if ( oldOutput )
489  {
490  newOutput->SetRequestedRegion(oldOutput);
491  newOutput->SetReleaseDataFlag( oldOutput->GetReleaseDataFlag() );
492  }
493  }
494 
495  this->Modified();
496 }
497 
501 void
504 {
505  if ( idx >= this->GetNumberOfIndexedOutputs() )
506  {
507  this->SetNumberOfIndexedOutputs(idx + 1);
508  }
509  this->SetOutput( m_IndexedOutputs[idx]->first, output );
510 }
511 
516 void
519 {
520  for ( DataObjectPointerArraySizeType idx = 0; idx < this->GetNumberOfIndexedOutputs(); ++idx )
521  {
522  if ( !this->GetOutput( idx ) )
523  {
524  this->SetNthOutput( idx, output );
525  return;
526  }
527  }
528  this->SetNthOutput( this->GetNumberOfIndexedOutputs(), output );
529 }
530 
534 void
537 {
538  if( this->GetNumberOfIndexedOutputs() != num )
539  {
540  if ( num < this->GetNumberOfIndexedOutputs() )
541  {
542  // NB: The primary output must never be removed from the map, or
543  // the indexed inputs array!
544 
545  // remove the extra outputs
546  for( DataObjectPointerArraySizeType i=std::max<DataObjectPointerArraySizeType>(num, 1);
547  i<this->GetNumberOfIndexedOutputs(); ++i )
548  {
549  // an output should never be NULL
550  itkAssertInDebugAndIgnoreInReleaseMacro( m_IndexedOutputs[i]->second );
551 
552  // let the output know we no longer want to associate with the
553  // object
554  m_IndexedOutputs[i]->second->DisconnectSource( this, m_IndexedOutputs[i]->first );
555 
556  m_Outputs.erase( m_IndexedOutputs[i]->first );
557  }
558 
559  m_IndexedOutputs.resize( std::max<DataObjectPointerArraySizeType>(num, 1) );
560 
561  if (num < 1 )
562  {
563  m_IndexedOutputs[0]->second = NULL;
564  }
565  }
566  else
567  {
568  for ( DataObjectPointerArraySizeType i = m_IndexedOutputs.size(); i < num; ++i)
569  {
570  DataObjectPointerMap::value_type p(this->MakeNameFromOutputIndex( i ), DataObjectPointer() );
571  // note: insert will not change value if it's already there.
572  m_IndexedOutputs.push_back ( m_Outputs.insert(p).first );
573  }
574  }
575 
576  this->Modified();
577  }
578 
579 }
580 
584 DataObject *
587 {
588  DataObjectPointerMap::iterator it = m_Outputs.find(key);
589  if ( it == m_Outputs.end() )
590  {
591  return NULL;
592  }
593  return it->second.GetPointer();
594 }
595 
596 const DataObject *
599 {
600  DataObjectPointerMap::const_iterator it = m_Outputs.find(key);
601  if ( it == m_Outputs.end() )
602  {
603  return NULL;
604  }
605  return it->second.GetPointer();
606 }
607 
611 DataObject *
614 {
615  return m_IndexedOutputs[i]->second;
616 }
617 
618 const DataObject *
621 {
622  return m_IndexedOutputs[i]->second;
623 }
624 
625 void
628 {
629  this->SetOutput(m_IndexedOutputs[0]->first, object);
630 }
631 
632 void
635 {
636  if( key != this->m_IndexedOutputs[0]->first )
637  {
638 
639  DataObjectPointerMap::value_type p(key, DataObjectPointer() );
640 
641  // note: insert will not change value if it's already there.
642  DataObjectPointerMap::iterator it = this->m_Outputs.insert( p ).first;
643 
644  if ( it->second.IsNull() )
645  {
646  it->second = this->m_IndexedOutputs[0]->second;
647  m_Outputs.erase(this->m_IndexedOutputs[0]);
648  }
649  this->m_IndexedOutputs[0] = it;
650 
651  this->Modified();
652  }
653 }
654 
655 bool
658 {
659  DataObjectPointerMap::const_iterator it = m_Outputs.find(key);
660  return it != m_Outputs.end();
661 }
662 
666 {
667  NameArray res;
668  res.reserve(m_Outputs.size());
669  for ( DataObjectPointerMap::const_iterator it = m_Outputs.begin(); it != m_Outputs.end(); ++it )
670  {
671  // only include the primary if it's required or set
672  if ( it->first != m_IndexedOutputs[0]->first
673  || it->second.IsNotNull() )
674  {
675  res.push_back( it->first );
676  }
677  }
678 
679  return res;
680 }
681 
682 // ProcessObject::ConstDataObjectPointerArray
683 // ProcessObject
684 // ::GetOutputs() const
685 // {
686 // ConstDataObjectPointerArray res;
687 // res.reserve(m_Outputs.size());
688 // for ( DataObjectPointerMap::const_iterator it = m_Outputs.begin(); it != m_Outputs.end(); ++it )
689 // {
690 // res.push_back( it->second.GetPointer() );
691 // }
692 // return res;
693 // }
694 
698 {
700  res.reserve(m_Outputs.size());
701  for ( DataObjectPointerMap::iterator it = m_Outputs.begin(); it != m_Outputs.end(); ++it )
702  {
703  // only include the primary if it's required or set
704  if ( it->first != m_IndexedOutputs[0]->first
705  || it->second.IsNotNull() )
706  {
707  res.push_back( it->second.GetPointer() );
708  }
709  }
710  return res;
711 }
712 
716 {
717  // only include the primary if it's required or set
718  if ( m_IndexedOutputs[0]->second.IsNotNull() )
719  {
720  return m_Outputs.size();
721  }
722  return m_Outputs.size() - 1;
723 }
724 
728 {
729  // this first element should always contain the primary output's
730  // name, if this is not true there is an internal logic error.
731  itkAssertInDebugAndIgnoreInReleaseMacro( m_IndexedOutputs.size() >= 1 );
732 
733  if( m_IndexedOutputs.size() > 1 )
734  {
735  return m_IndexedOutputs.size();
736  }
737  return this->GetPrimaryOutput() != NULL;
738 }
739 
740 // ProcessObject::ConstDataObjectPointerArray
741 // ProcessObject
742 // ::GetIndexedOutputs() const
743 // {
744 // ConstDataObjectPointerArray res(this->GetNumberOfIndexedOutputs());
745 // for ( unsigned int i = 0; i < this->GetNumberOfIndexedOutputs(); i++ )
746 // {
747 // res[i] = this->GetOutput(i);
748 // }
749 // return res;
750 // }
751 
755 {
756  DataObjectPointerArray res(this->GetNumberOfIndexedOutputs());
757  for ( DataObjectPointerArraySizeType i = 0; i < this->GetNumberOfIndexedOutputs(); i++ )
758  {
759  res[i] = this->GetOutput(i);
760  }
761  return res;
762 }
763 
767 DataObject *
770 {
771  DataObjectPointerMap::iterator it = m_Inputs.find(key);
772  if ( it == m_Inputs.end() )
773  {
774  return NULL;
775  }
776  return it->second.GetPointer();
777 }
778 
779 const DataObject *
782 {
783  DataObjectPointerMap::const_iterator it = m_Inputs.find(key);
784  if ( it == m_Inputs.end() )
785  {
786  return NULL;
787  }
788  return it->second.GetPointer();
789 }
790 
791 void
794 {
795  if ( m_IndexedInputs[0]->second != object )
796  {
797  m_IndexedInputs[0]->second = object;
798  this->Modified();
799  }
800 }
801 
802 void
805 {
806  this->RemoveRequiredInputName( m_IndexedInputs[0]->first );
807  this->AddRequiredInputName( key, 0 );
808 }
809 
810 bool
813 {
814  DataObjectPointerMap::const_iterator it = m_Inputs.find(key);
815  return it != m_Inputs.end();
816 }
817 
821 {
822  NameArray res;
823  res.reserve(m_Inputs.size());
824  for ( DataObjectPointerMap::const_iterator it = m_Inputs.begin(); it != m_Inputs.end(); ++it )
825  {
826  // only include the primary if it's required or set
827  if ( it->first != m_IndexedInputs[0]->first
828  || it->second.IsNotNull()
829  || this->IsRequiredInputName(it->first) )
830  {
831  res.push_back( it->first );
832  }
833  }
834  return res;
835 }
836 
837 
838 bool
841 {
842  if( name.empty() )
843  {
844  itkExceptionMacro("An empty string can't be used as an input identifier");
845  }
846 
847  if( !m_RequiredInputNames.insert( name ).second )
848  {
849  return false;
850  }
851 
852  // note: insert will not change value if it's already there.
853  m_Inputs.insert( DataObjectPointerMap::value_type(name, DataObjectPointer() ) );
854 
855  if( name == m_IndexedInputs[0]->first && m_NumberOfRequiredInputs == 0 )
856  {
857  m_NumberOfRequiredInputs = 1;
858  }
859  this->Modified();
860  return true;
861 }
862 
863 bool
867 {
868  if( name.empty() )
869  {
870  itkExceptionMacro("An empty string can't be used as an input identifier");
871  }
872 
873  if( !m_RequiredInputNames.insert( name ).second )
874  {
875  return false;
876  }
877 
878  DataObjectPointerMap::value_type p(name, DataObjectPointer() );
879  // note: insert will not change value if it's already there.
880  DataObjectPointerMap::iterator it = m_Inputs.insert(p).first;
881 
882  if ( idx >= this->GetNumberOfIndexedInputs() )
883  {
884  this->SetNumberOfIndexedInputs(idx + 1);
885  }
886  else if( !it->second )
887  {
888  // if the old index had a data object move that to the new name
889  it->second = this->GetInput( m_IndexedInputs[idx]->first );
890  }
891 
892 
893  m_IndexedInputs[idx] = it;
894 
895  if( name == m_IndexedInputs[0]->first && m_NumberOfRequiredInputs == 0 )
896  {
897  m_NumberOfRequiredInputs = 1;
898  }
899 
900  this->Modified();
901  return true;
902 }
903 
904 bool
907 {
908  if( m_RequiredInputNames.erase( name ) )
909  {
910  if( name == m_IndexedInputs[0]->first && m_NumberOfRequiredInputs == 1 )
911  {
912  m_NumberOfRequiredInputs = 0;
913  }
914  this->Modified();
915  return true;
916  }
917  return false;
918 }
919 
920 bool
923 {
924  return m_RequiredInputNames.find( name ) != m_RequiredInputNames.end();
925 }
926 
927 void
930 {
931  m_RequiredInputNames.clear();
932  for ( NameArray::const_iterator it = names.begin(); it != names.end(); ++it )
933  {
934  this->AddRequiredInputName( *it );
935  }
936  this->Modified();
937 }
938 
942 {
943  NameArray res;
944  res.reserve(m_RequiredInputNames.size());
945  for ( NameSet::const_iterator it = m_RequiredInputNames.begin(); it != m_RequiredInputNames.end(); ++it )
946  {
947  res.push_back( *it );
948  }
949  return res;
950 }
951 
952 // ProcessObject::ConstDataObjectPointerArray
953 // ProcessObject
954 // ::GetInputs() const
955 // {
956 // ConstDataObjectPointerArray res;
957 // res.reserve(m_Inputs.size());
958 // for ( DataObjectPointerMap::const_iterator it = m_Inputs.begin(); it != m_Inputs.end(); ++it )
959 // {
960 // res.push_back( it->second.GetPointer() );
961 // }
962 // return res;
963 // }
964 
968 {
970  res.reserve(m_Inputs.size());
971  for ( DataObjectPointerMap::iterator it = m_Inputs.begin(); it != m_Inputs.end(); ++it )
972  {
973  // only include the primary if it's required or set
974  if ( it->first != m_IndexedInputs[0]->first
975  || it->second.IsNotNull()
976  || this->IsRequiredInputName(it->first) )
977  {
978  res.push_back( it->second.GetPointer() );
979  }
980  }
981  return res;
982 }
983 
987 {
988  // only include the primary if it's required or set
989  if ( m_IndexedInputs[0]->second.IsNotNull()
990  || this->IsRequiredInputName(m_IndexedInputs[0]->first) )
991  {
992  return m_Inputs.size();
993  }
994  return m_Inputs.size() - 1;
995 }
996 
1000 {
1001  // this first element should always contain the primary input's
1002  // name, if this is not true there is an internal logic error.
1003  itkAssertInDebugAndIgnoreInReleaseMacro( m_IndexedInputs.size() >= 1 );
1004 
1005  if ( m_IndexedInputs.size() > 1 )
1006  {
1007  return m_IndexedInputs.size();
1008  }
1009  return this->GetPrimaryInput() != NULL;
1010 }
1011 
1012 // ProcessObject::ConstDataObjectPointerArray
1013 // ProcessObject
1014 // ::GetIndexedInputs() const
1015 // {
1016 // ConstDataObjectPointerArray res(this->GetNumberOfIndexedInputs());
1017 // for ( DataObjectPointerArraySizeType i = 0; i < this->GetNumberOfIndexedInputs(); i++ )
1018 // {
1019 // res[i] = this->GetInput(i);
1020 // }
1021 // return res;
1022 // }
1023 
1027 {
1028  DataObjectPointerArray res(this->GetNumberOfIndexedInputs());
1029  for ( DataObjectPointerArraySizeType i = 0; i < this->GetNumberOfIndexedInputs(); i++ )
1030  {
1031  res[i] = this->GetInput(i);
1032  }
1033  return res;
1034 }
1035 
1039 {
1040  if( idx == 0 )
1041  {
1042  return m_IndexedInputs[0]->first;
1043  }
1044  return this->MakeNameFromIndex(idx);
1045 }
1046 
1050 {
1051  if( idx == 0 )
1052  {
1053  return this->m_IndexedOutputs[0]->first;
1054  }
1055  return this->MakeNameFromIndex(idx);
1056 }
1057 
1061 {
1062  if ( idx < ITK_GLOBAL_INDEX_NAMES_NUMBER )
1063  {
1064  return ProcessObject::DataObjectIdentifierType( globalIndexNames[idx] );
1065  }
1066  else
1067  {
1068  char buf[2+21]; // a 64-bit integer is ~20 decimal places max
1069  sprintf(buf, "_%u", static_cast<unsigned int>(idx));
1070  return buf;
1071  }
1072 }
1073 
1077 {
1078  if( name == m_IndexedInputs[0]->first )
1079  {
1080  itkDebugMacro("MakeIndexFromName("<<name<<") -> 0");
1081  return 0;
1082  }
1083  return this->MakeIndexFromName( name );
1084 }
1085 
1089 {
1090  if( name == this->m_IndexedOutputs[0]->first )
1091  {
1092  itkDebugMacro("MakeIndexFromName("<<name<<") -> 0");
1093  return 0;
1094  }
1095  return this->MakeIndexFromName( name );
1096 }
1097 
1101 {
1102  DataObjectIdentifierType baseName = "_";
1103  DataObjectPointerArraySizeType baseSize = baseName.size();
1104  if( name.size() <= baseSize || name.substr(0, baseSize) != baseName )
1105  {
1106  itkDebugMacro("MakeIndexFromName("<<name<<") -> exception bad base name");
1107  itkExceptionMacro(<<"Not an indexed data object: " << name);
1108  }
1109  DataObjectIdentifierType idxStr = name.substr(baseSize);
1111  if( !(std::istringstream(idxStr) >> idx) )
1112  {
1113  itkDebugMacro("MakeIndexFromName("<<name<<") -> exception not an index");
1114  itkExceptionMacro(<<"Not an indexed data object: " << name);
1115  }
1116  itkDebugMacro("MakeIndexFromName("<<name<<") -> "<< idx);
1117  return idx;
1118 }
1119 
1120 bool
1123 {
1124  if( name == m_IndexedInputs[0]->first )
1125  {
1126  return true;
1127  }
1128  for ( DataObjectPointerArraySizeType i = 0; i < m_IndexedInputs.size(); ++i)
1129  {
1130  if ( m_IndexedInputs[i]->first == name )
1131  {
1132  return true;
1133  }
1134  }
1135  return false;
1136 }
1137 
1138 bool
1141 {
1142  if( name == m_IndexedOutputs[0]->first )
1143  {
1144  return true;
1145  }
1146  for ( DataObjectPointerArraySizeType i = 0; i < m_IndexedOutputs.size(); ++i)
1147  {
1148  if ( m_IndexedOutputs[i]->first == name )
1149  {
1150  return true;
1151  }
1152  }
1153  return false;
1154 }
1155 
1161 void
1163 ::UpdateProgress(float progress)
1164 {
1165  // Clamp the value to be between 0 and 1.
1166  m_Progress = std::max(progress, 0.0f);
1167  m_Progress = std::min(m_Progress, 1.0f);
1168 
1169  this->InvokeEvent( ProgressEvent() );
1170 }
1171 
1175 bool
1178 {
1179  if ( this->GetPrimaryOutput() )
1180  {
1181  return this->GetPrimaryOutput()->GetReleaseDataFlag();
1182  }
1183  itkWarningMacro(<< "Output doesn't exist!");
1184  return false;
1185 }
1186 
1190 void
1193 {
1194  for ( DataObjectPointerMap::iterator it=m_Outputs.begin(); it != m_Outputs.end(); ++it )
1195  {
1196  if ( it->second )
1197  {
1198  it->second->SetReleaseDataFlag(val);
1199  }
1200  }
1201 }
1202 
1206 void
1208 ::PrintSelf(std::ostream & os, Indent indent) const
1209 {
1210  Superclass::PrintSelf(os, indent);
1211 
1212  Indent indent2 = indent.GetNextIndent();
1213  if ( !m_Inputs.empty() )
1214  {
1215  os << indent << "Inputs: " << std::endl;
1216  for ( DataObjectPointerMap::const_iterator it = m_Inputs.begin(); it != m_Inputs.end(); ++it )
1217  {
1218  std::string req = "";
1219  if( this->IsRequiredInputName( it->first ) )
1220  {
1221  req = " *";
1222  }
1223  os << indent2 << it->first<< ": (" << it->second.GetPointer() << ")" << req << std::endl;
1224  }
1225  }
1226  else
1227  {
1228  os << indent << "No Inputs\n";
1229  }
1230 
1231  os << indent << "Indexed Inputs: " << std::endl;
1232  unsigned int idx = 0;
1233  for ( std::vector< DataObjectPointerMap::iterator >::const_iterator it = m_IndexedInputs.begin();
1234  it != m_IndexedInputs.end();
1235  ++it, ++idx)
1236  {
1237  os << indent2 << idx << ": " << (*it)->first << " (" << (*it)->second.GetPointer() << ")"<< std::endl;
1238  }
1239 
1240  if( !m_RequiredInputNames.empty() )
1241  {
1242  os << indent << "Required Input Names: ";
1243  for( NameSet::const_iterator it = m_RequiredInputNames.begin(); it != m_RequiredInputNames.end(); ++it )
1244  {
1245  if( it != m_RequiredInputNames.begin() )
1246  {
1247  os << ", ";
1248  }
1249  os << *it;
1250  }
1251  os << std::endl;
1252  }
1253  else
1254  {
1255  os << indent << "No Required Input Names" << std::endl;
1256  }
1257  os << indent << "NumberOfRequiredInputs: "
1258  << m_NumberOfRequiredInputs << std::endl;
1259 
1260  if ( !m_Outputs.empty() )
1261  {
1262  os << indent << "Outputs: " << std::endl;
1263  for ( DataObjectPointerMap::const_iterator it = m_Outputs.begin(); it != m_Outputs.end(); ++it )
1264  {
1265  os << indent2 << it->first << ": (" << it->second.GetPointer() << ")" << std::endl;
1266  }
1267  }
1268  else
1269  {
1270  os << indent << "No Outputs\n";
1271  }
1272  os << indent << "Indexed Outputs: " << std::endl;
1273  idx = 0;
1274  for ( std::vector< DataObjectPointerMap::iterator >::const_iterator it = m_IndexedOutputs.begin();
1275  it != m_IndexedOutputs.end();
1276  ++it, ++idx)
1277  {
1278  os << indent2 << idx << ": " << (*it)->first << " (" << (*it)->second.GetPointer() << ")"<< std::endl;
1279  }
1280 
1281  os << indent << "NumberOfRequiredOutputs: "
1282  << m_NumberOfRequiredOutputs << std::endl;
1283 
1284  os << indent << "Number Of Threads: "
1285  << m_NumberOfThreads << std::endl;
1286 
1287  os << indent << "ReleaseDataFlag: "
1288  << ( this->GetReleaseDataFlag() ? "On" : "Off" ) << std::endl;
1289 
1290  os << indent << "ReleaseDataBeforeUpdateFlag: "
1291  << ( m_ReleaseDataBeforeUpdateFlag ? "On" : "Off" ) << std::endl;
1292 
1293  os << indent << "AbortGenerateData: " << ( m_AbortGenerateData ? "On" : "Off" ) << std::endl;
1294  os << indent << "Progress: " << m_Progress << std::endl;
1295 
1296  os << indent << "Multithreader: " << std::endl;
1297  m_Threader->PrintSelf( os, indent.GetNextIndent() );
1298 }
1299 
1308 void
1311 {
1312  if ( this->GetPrimaryOutput() )
1313  {
1314  this->GetPrimaryOutput()->Update();
1315  }
1316 }
1317 
1318 void
1321 {
1322  if ( this->GetPrimaryOutput() )
1323  {
1324  this->GetPrimaryOutput()->ResetPipeline();
1325  }
1326  else
1327  {
1328  // important to make it work on process objects without outputs
1329  this->PropagateResetPipeline();
1330  }
1331 }
1332 
1333 void
1336 {
1337  //
1338  // Reset this object.
1339  //
1340  // Clear the updating flag.
1341  m_Updating = 0;
1342 
1343  //
1344  // Loop through the inputs
1345  //
1346  for ( DataObjectPointerMap::iterator it=m_Inputs.begin(); it != m_Inputs.end(); ++it )
1347  {
1348  if ( it->second )
1349  {
1350  it->second->PropagateResetPipeline();
1351  }
1352  }
1353 }
1354 
1358 void
1361 {
1362 
1366  for( NameSet::const_iterator it = this->m_RequiredInputNames.begin(); it != this->m_RequiredInputNames.end(); ++it )
1367  {
1368  if ( this->GetInput( *it ) == NULL )
1369  {
1370  itkExceptionMacro(<< "Input " << *it << " is required but not set.");
1371  }
1372  }
1373 
1377  NameSet::const_iterator i = m_RequiredInputNames.begin();
1378  while (i != m_RequiredInputNames.end())
1379  {
1380  if ( this->GetInput(*i) == NULL )
1381  {
1382  itkExceptionMacro( << "Required Input " << *i << "is not specified!"
1383  << " The required inputs are expected to be the first inputs.");
1384 
1385  }
1386  ++i;
1387  }
1388 
1392  const DataObjectPointerArraySizeType validIndexedInputs = this->GetNumberOfValidRequiredInputs();
1393 
1394  if ( validIndexedInputs < this->m_NumberOfRequiredInputs )
1395  {
1396  itkExceptionMacro(<< "At least " << this->m_NumberOfRequiredInputs
1397  << " of the first " << this->m_NumberOfRequiredInputs
1398  << " indexed inputs are required but only " << validIndexedInputs
1399  << " are specified."
1400  << " The required inputs are expected to be the first inputs.");
1401  }
1402 }
1403 
1404 
1408 void
1411 {
1412 }
1413 
1414 
1418 void
1421 {
1422  ModifiedTimeType t1, t2;
1423  DataObject * input;
1424  DataObject * output;
1425 
1429  if ( m_Updating )
1430  {
1437  this->Modified();
1438  return;
1439  }
1440 
1447  this->VerifyPreconditions();
1448 
1455  t1 = this->GetMTime();
1456 
1460  for ( DataObjectPointerMap::iterator it=m_Inputs.begin(); it != m_Inputs.end(); ++it )
1461  {
1462  if ( it->second )
1463  {
1464  input = it->second;
1465 
1469  m_Updating = true;
1470  input->UpdateOutputInformation();
1471  m_Updating = false;
1472 
1477  t2 = input->GetPipelineMTime();
1478 
1479  if ( t2 > t1 )
1480  {
1481  t1 = t2;
1482  }
1483 
1488  t2 = input->GetMTime();
1489  if ( t2 > t1 )
1490  {
1491  t1 = t2;
1492  }
1493  }
1494  }
1495 
1503  if ( t1 > m_OutputInformationMTime.GetMTime() )
1504  {
1505  for ( DataObjectPointerMap::iterator it=m_Outputs.begin(); it != m_Outputs.end(); ++it )
1506  {
1507  output = it->second;
1508  if ( output )
1509  {
1510  output->SetPipelineMTime(t1);
1511  }
1512  }
1513 
1519  this->VerifyInputInformation();
1520 
1524  this->GenerateOutputInformation();
1525 
1529  m_OutputInformationMTime.Modified();
1530  }
1531 }
1532 
1536 void
1539 {
1543  if ( m_Updating )
1544  {
1545  return;
1546  }
1547 
1555  this->EnlargeOutputRequestedRegion(output);
1556 
1564  this->GenerateOutputRequestedRegion(output);
1565 
1574  this->GenerateInputRequestedRegion();
1575 
1580  m_Updating = true;
1581  for ( DataObjectPointerMap::iterator it=m_Inputs.begin(); it != m_Inputs.end(); ++it )
1582  {
1583  if ( it->second )
1584  {
1585  it->second->PropagateRequestedRegion();
1586  }
1587  }
1588  m_Updating = false;
1589 }
1590 
1596 void
1599 {
1600  for ( DataObjectPointerMap::iterator it=m_Inputs.begin(); it != m_Inputs.end(); ++it )
1601  {
1602  if ( it->second )
1603  {
1604  it->second->SetRequestedRegionToLargestPossibleRegion();
1605  }
1606  }
1607 }
1608 
1612 void
1615 {
1616  for ( DataObjectPointerMap::iterator it=m_Outputs.begin(); it != m_Outputs.end(); ++it )
1617  {
1618  if ( it->second && it->second != output )
1619  {
1620  it->second->SetRequestedRegion(output);
1621  }
1622  }
1623 }
1624 
1628 void
1631 {
1632  if ( this->GetReleaseDataBeforeUpdateFlag() )
1633  {
1634  for ( DataObjectPointerMap::iterator it=m_Outputs.begin(); it != m_Outputs.end(); ++it )
1635  {
1636  if ( it->second )
1637  {
1638  it->second->PrepareForNewData();
1639  }
1640  }
1641  }
1642 }
1643 
1647 void
1650 {
1651  for ( DataObjectPointerMap::iterator it=m_Inputs.begin(); it != m_Inputs.end(); ++it )
1652  {
1653  if ( it->second )
1654  {
1655  if ( it->second->ShouldIReleaseData() )
1656  {
1657  it->second->ReleaseData();
1658  }
1659  }
1660  }
1661 }
1662 
1666 void
1668 ::UpdateOutputData( DataObject * itkNotUsed(output) )
1669 {
1673  if ( m_Updating )
1674  {
1675  return;
1676  }
1677 
1681  this->PrepareOutputs();
1682 
1689  m_Updating = true;
1690  if ( m_Inputs.size() == 1 )
1691  {
1692  if ( this->GetPrimaryInput() )
1693  {
1694  this->GetPrimaryInput()->UpdateOutputData();
1695  }
1696  }
1697  else
1698  {
1699  for ( DataObjectPointerMap::iterator it=m_Inputs.begin(); it != m_Inputs.end(); ++it )
1700  {
1701  if ( it->second )
1702  {
1703  it->second->PropagateRequestedRegion();
1704  it->second->UpdateOutputData();
1705  }
1706  }
1707  }
1708 
1717  this->CacheInputReleaseDataFlags();
1718 
1722  this->InvokeEvent( StartEvent() );
1723 
1728  m_AbortGenerateData = false;
1729  m_Progress = 0.0f;
1730 
1731  try
1732  {
1733  this->GenerateData();
1734  }
1735  catch ( ProcessAborted & excp )
1736  {
1737  this->InvokeEvent( AbortEvent() );
1738  this->ResetPipeline();
1739  this->RestoreInputReleaseDataFlags();
1740  throw &excp;
1741  }
1742  catch (...)
1743  {
1744  this->ResetPipeline();
1745  this->RestoreInputReleaseDataFlags();
1746  throw;
1747  }
1748 
1754  if ( m_AbortGenerateData )
1755  {
1756  this->UpdateProgress(1.0f);
1757  }
1758 
1762  this->InvokeEvent( EndEvent() );
1763 
1767  for ( DataObjectPointerMap::iterator it=m_Outputs.begin(); it != m_Outputs.end(); ++it )
1768  {
1769  if ( it->second )
1770  {
1771  it->second->DataHasBeenGenerated();
1772  }
1773  }
1774 
1778  this->RestoreInputReleaseDataFlags();
1779 
1783  this->ReleaseInputs();
1784 
1785  // Mark that we are no longer updating the data in this filter
1786  m_Updating = false;
1787 }
1788 
1792 void
1795 {
1796  m_CachedInputReleaseDataFlags.clear();
1797  for ( DataObjectPointerMap::iterator it = m_Inputs.begin(); it != m_Inputs.end(); ++it )
1798  {
1799  if ( it->second )
1800  {
1801  m_CachedInputReleaseDataFlags[it->first] = it->second->GetReleaseDataFlag();
1802  it->second->ReleaseDataFlagOff();
1803  }
1804  else
1805  {
1806  m_CachedInputReleaseDataFlags[it->first] = false;
1807  }
1808  }
1809 }
1810 
1814 void
1817 {
1818  for ( DataObjectPointerMap::iterator it = m_Inputs.begin(); it != m_Inputs.end(); ++it )
1819  {
1820  if ( it->second )
1821  {
1822  it->second->SetReleaseDataFlag(m_CachedInputReleaseDataFlags[it->first]);
1823  }
1824  }
1825  m_CachedInputReleaseDataFlags.clear();
1826 }
1827 
1831 void
1834 {
1835  DataObject * input = this->GetPrimaryInput();
1836 
1837  if ( input )
1838  {
1839  for ( DataObjectPointerMap::iterator it=m_Outputs.begin(); it != m_Outputs.end(); ++it )
1840  {
1841  if ( it->second )
1842  {
1843  it->second->CopyInformation(input);
1844  }
1845  }
1846  }
1847 }
1848 
1849 void
1852 {
1853  this->UpdateOutputInformation();
1854 
1855  if ( this->GetPrimaryOutput() )
1856  {
1857  this->GetPrimaryOutput()->SetRequestedRegionToLargestPossibleRegion();
1858  this->GetPrimaryOutput()->Update();
1859  }
1860 }
1861 
1862 template< typename TDomainPartitioner, typename TAssociate >
1865 {
1866 }
1867 
1868 template< typename TDomainPartitioner, typename TAssociate >
1871 {
1872 }
1873 
1874 template< typename TDomainPartitioner, typename TAssociate >
1875 void
1878 {
1879  MultiThreader * multiThreader = this->m_Associate->GetMultiThreader();
1880  this->SetMultiThreader( multiThreader );
1881  multiThreader->SetNumberOfThreads( this->m_Associate->GetNumberOfThreads() );
1882 
1883  Superclass::DetermineNumberOfThreadsUsed();
1884 }
1885 
1889 void
1892 {
1893  if( m_NumberOfRequiredInputs != nb )
1894  {
1895  m_NumberOfRequiredInputs = nb;
1896  this->Modified();
1897  if( m_NumberOfRequiredInputs > 0 )
1898  {
1899  this->AddRequiredInputName( m_IndexedInputs[0]->first );
1900  }
1901  if( m_NumberOfRequiredInputs == 0 )
1902  {
1903  this->RemoveRequiredInputName( m_IndexedInputs[0]->first );
1904  }
1905  }
1906 }
1907 #if !defined(ITK_LEGACY_REMOVE)
1908 
1911 void
1912 ProcessObject
1913 ::SetNumberOfInputs(DataObjectPointerArraySizeType num)
1914 {
1915  this->SetNumberOfIndexedInputs(num);
1916 }
1920 void
1921 ProcessObject
1922 ::SetNumberOfOutputs(DataObjectPointerArraySizeType num)
1923 {
1924  this->SetNumberOfIndexedOutputs(num);
1925 }
1926 
1930 void
1932 ::RemoveInput(DataObject * input)
1933 {
1934  if( !input )
1935  {
1936  return;
1937  }
1938  DataObjectPointerArraySizeType nb = this->GetNumberOfIndexedInputs();
1939  for( DataObjectPointerArraySizeType i = 0; i < nb; i++ )
1940  {
1941  if( this->GetInput(i) == input )
1942  {
1943  this->RemoveInput( i );
1944  return;
1945  }
1946  }
1947  itkDebugMacro("tried to remove an input that was not in the list");
1948 }
1949 
1953 void
1955 ::RemoveOutput(DataObject * output)
1956 {
1957  if( !output )
1958  {
1959  return;
1960  }
1961  DataObjectPointerArraySizeType nb = this->GetNumberOfIndexedOutputs();
1962  for( DataObjectPointerArraySizeType i = 0; i < nb; i++ )
1963  {
1964  if( this->GetOutput(i) == output )
1965  {
1966  this->RemoveOutput( i );
1967  return;
1968  }
1969  }
1970  itkDebugMacro("tried to remove an output that was not in the list");
1971 }
1972 
1973 
1974 #endif
1975 
1976 } // end namespace itk

Generated at Sat Mar 8 2014 15:23:52 for Orfeo Toolbox with doxygen 1.8.3.1