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

  Program:   Visualization Toolkit
  Module:    vtkTable.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
#include "vtkArrayIteratorIncludes.h"
22
#include "vtkTable.h"
23
24
25

#include "vtkAbstractArray.h"
#include "vtkDataArray.h"
26
#include "vtkDataSetAttributes.h"
27
28
29
30
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkStringArray.h"
31
#include "vtkUnicodeStringArray.h"
32
33
34
35
36
37
38
#include "vtkVariantArray.h"

//
// Standard functions
//

vtkStandardNewMacro(vtkTable);
39
vtkCxxSetObjectMacro(vtkTable, RowData, vtkDataSetAttributes);
40
41
42
43

//----------------------------------------------------------------------------
vtkTable::vtkTable()
{
44
  this->RowArray = vtkVariantArray::New();
45
  this->RowData = vtkDataSetAttributes::New();
46
47
48
49
50

  this->Information->Set(vtkDataObject::DATA_EXTENT_TYPE(), VTK_PIECES_EXTENT);
  this->Information->Set(vtkDataObject::DATA_PIECE_NUMBER(), -1);
  this->Information->Set(vtkDataObject::DATA_NUMBER_OF_PIECES(), 1);
  this->Information->Set(vtkDataObject::DATA_NUMBER_OF_GHOST_LEVELS(), 0);
51
52
53
}

//----------------------------------------------------------------------------
54
55
vtkTable::~vtkTable()
{
56
57
58
59
60
61
62
63
  if (this->RowArray)
    {
    this->RowArray->Delete();
    }
  if (this->RowData)
    {
    this->RowData->Delete();
    }
64
65
66
}

//----------------------------------------------------------------------------
67
68
69
void vtkTable::PrintSelf(ostream &os, vtkIndent indent)
{
  vtkDataObject::PrintSelf(os, indent);
70
71
72
73
74
  os << indent << "RowData: " << (this->RowData ? "" : "(none)") << endl;
  if (this->RowData)
    {
    this->RowData->PrintSelf(os, indent.GetNextIndent());
    }
75
76
}

77
//----------------------------------------------------------------------------
78
void vtkTable::Dump( unsigned int colWidth, int rowLimit )
79

80
{
81
82
83
84
85
86
  if ( ! this->GetNumberOfColumns() )
    {
    cout << "++\n++\n";
    return;
    }

87
88
89
90
91
  vtkStdString lineStr;
  for ( int c = 0; c < this->GetNumberOfColumns(); ++ c )
    {
    lineStr += "+-";

92
    for ( unsigned int i = 0; i < colWidth; ++ i )
93
94
95
96
97
98
99
100
      {
      lineStr += "-";
      }
    }
  lineStr += "-+\n";

  cout << lineStr;

Philippe Pebay's avatar
Philippe Pebay committed
101
  for ( int c = 0; c < this->GetNumberOfColumns(); ++ c )
102
103
    {
    cout << "| ";
104
105
    const char* name = this->GetColumnName( c );
    vtkStdString str = name ? name : "";
106

107
    if ( colWidth < str.length() )
108
      {
109
110
111
112
113
      cout << str.substr( 0, colWidth );
      }
    else
      {
      cout << str;
114
      for ( unsigned int i = static_cast<unsigned int>(str.length()); i < colWidth; ++ i )
115
116
117
118
119
120
121
122
123
        {
        cout << " ";
        }
      }
    }

  cout << " |\n"
       << lineStr;

124
  if ( rowLimit != 0 )
125
    {
126
    for ( vtkIdType r = 0; r < this->GetNumberOfRows(); ++ r )
127
      {
128
      for ( int c = 0; c < this->GetNumberOfColumns(); ++ c )
129
        {
130
131
132
133
        cout << "| ";
        vtkStdString str = this->GetValue( r, c ).ToString();

        if ( colWidth < str.length() )
134
          {
135
136
137
138
139
140
141
142
143
          cout << str.substr( 0, colWidth );
          }
        else
          {
          cout << str;
          for ( unsigned int i = static_cast<unsigned int>(str.length()); i < colWidth; ++ i )
            {
            cout << " ";
            }
144
145
          }
        }
146
147
148
      cout << " |\n";
      if ( rowLimit != -1 && r >= rowLimit )
        break;
149
      }
150
151
    cout << lineStr;
    cout.flush();
152
153
154
    }
}
 
155
//----------------------------------------------------------------------------
156
void vtkTable::Initialize()
157
{
158
159
  this->Superclass::Initialize();
  if (this->RowData)
160
    {
161
    this->RowData->Initialize();
162
163
164
165
    }
}

//----------------------------------------------------------------------------
166
unsigned long vtkTable::GetActualMemorySize()
167
{
168
169
  return this->RowData->GetActualMemorySize() +
         this->Superclass::GetActualMemorySize();
170
171
}

172
173
174
175
176
177
178
//
// Row functions
//

//----------------------------------------------------------------------------
vtkIdType vtkTable::GetNumberOfRows()
{
179
180
181
182
183
  if (this->GetNumberOfColumns() > 0)
    {
    return this->GetColumn(0)->GetNumberOfTuples();
    }
  return 0;
184
185
}

186
187
188
189
190
191
192
193
194
//----------------------------------------------------------------------------
void vtkTable::SetNumberOfRows( vtkIdType n )
{
  if( this->RowData )
    {
      this->RowData->SetNumberOfTuples( n );
    }
}

195
196
197
//----------------------------------------------------------------------------
vtkVariantArray* vtkTable::GetRow(vtkIdType row)
{
198
199
200
  vtkIdType ncol = this->GetNumberOfColumns();
  this->RowArray->SetNumberOfTuples(ncol);
  for (vtkIdType i = 0; i < ncol; i++)
201
    {
202
    this->RowArray->SetValue(i, this->GetValue(row, i));
203
204
205
206
207
208
209
    }
  return this->RowArray;
}

//----------------------------------------------------------------------------
void vtkTable::GetRow(vtkIdType row, vtkVariantArray *values)
{
210
211
212
  vtkIdType ncol = this->GetNumberOfColumns();
  values->SetNumberOfTuples(ncol);
  for (vtkIdType i = 0; i < ncol; i++)
213
    {
214
    values->SetValue(i, this->GetValue(row, i));
215
216
217
218
    }
}

//----------------------------------------------------------------------------
219
void vtkTable::SetRow(vtkIdType row, vtkVariantArray *values)
Jeff Baumes's avatar
Jeff Baumes committed
220
{
221
222
223
224
225
226
  vtkIdType ncol = this->GetNumberOfColumns();
  if (values->GetNumberOfTuples() != ncol)
    {
    vtkErrorMacro(<< "Incorrect number of tuples in SetRow");
    }
  for (vtkIdType i = 0; i < ncol; i++)
Jeff Baumes's avatar
Jeff Baumes committed
227
228
229
230
231
232
    {
    this->SetValue(row, i, values->GetValue(i));
    }
}

//----------------------------------------------------------------------------
233
vtkIdType vtkTable::InsertNextBlankRow(double default_num_val)
234
{
235
236
  vtkIdType ncol = this->GetNumberOfColumns();
  for (vtkIdType i = 0; i < ncol; i++)
237
    {
238
    vtkAbstractArray* arr = this->GetColumn(i);
239
    int comps = arr->GetNumberOfComponents();
240
    if (vtkDataArray::SafeDownCast(arr))
241
242
243
244
245
      {
      vtkDataArray* data = vtkDataArray::SafeDownCast(arr);
      double* tuple = new double[comps];
      for (int j = 0; j < comps; j++)
        {
246
        tuple[j] = default_num_val;
247
248
249
250
        }
      data->InsertNextTuple(tuple);
      delete[] tuple;
      }
251
    else if (vtkStringArray::SafeDownCast(arr))
252
253
254
255
256
257
258
      {
      vtkStringArray* data = vtkStringArray::SafeDownCast(arr);
      for (int j = 0; j < comps; j++)
        {
        data->InsertNextValue(vtkStdString(""));
        }
      }
259
    else if (vtkVariantArray::SafeDownCast(arr))
260
261
262
263
264
265
266
      {
      vtkVariantArray* data = vtkVariantArray::SafeDownCast(arr);
      for (int j = 0; j < comps; j++)
        {
        data->InsertNextValue(vtkVariant());
        }
      }
267
268
269
270
271
272
273
274
    else if (vtkUnicodeStringArray::SafeDownCast(arr))
      {
      vtkUnicodeStringArray* data = vtkUnicodeStringArray::SafeDownCast(arr);
      for (int j = 0; j < comps; j++)
        {
        data->InsertNextValue(vtkUnicodeString::from_utf8(""));
        }
      }
275
276
277
278
    else
      {
      vtkErrorMacro(<< "Unsupported array type for InsertNextBlankRow");
      }
279
    }
280
  return this->GetNumberOfRows() - 1;
281
282
283
284
285
}

//----------------------------------------------------------------------------
vtkIdType vtkTable::InsertNextRow(vtkVariantArray* values)
{
286
287
288
289
290
  vtkIdType ncol = this->GetNumberOfColumns();
  if (values->GetNumberOfTuples() != ncol)
    {
    vtkErrorMacro(<< "Incorrect number of tuples in SetRow");
    }
291
  vtkIdType row = this->InsertNextBlankRow();
292
  for (vtkIdType i = 0; i < ncol; i++)
293
294
295
296
297
298
299
300
301
    {
    this->SetValue(row, i, values->GetValue(i));
    }
  return row;
}

//----------------------------------------------------------------------------
void vtkTable::RemoveRow(vtkIdType row)
{
302
303
  vtkIdType ncol = this->GetNumberOfColumns();
  for (vtkIdType i = 0; i < ncol; i++)
304
    {
305
    vtkAbstractArray* arr = this->GetColumn(i);
306
    int comps = arr->GetNumberOfComponents();
307
    if (vtkDataArray::SafeDownCast(arr))
308
309
310
311
      {
      vtkDataArray* data = vtkDataArray::SafeDownCast(arr);
      data->RemoveTuple(row);
      }
312
    else if (vtkStringArray::SafeDownCast(arr))
313
314
315
316
317
318
319
320
321
      {
      // Manually move all elements past the index back one place.
      vtkStringArray* data = vtkStringArray::SafeDownCast(arr);
      for (int j = comps*row; j < comps*data->GetNumberOfTuples() - 1; j++)
        {
        data->SetValue(j, data->GetValue(j+1));
        }
      data->Resize(data->GetNumberOfTuples() - 1);
      }
322
    else if (vtkVariantArray::SafeDownCast(arr))
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
      {
      // Manually move all elements past the index back one place.
      vtkVariantArray* data = vtkVariantArray::SafeDownCast(arr);
      for (int j = comps*row; j < comps*data->GetNumberOfTuples() - 1; j++)
        {
        data->SetValue(j, data->GetValue(j+1));
        }
      data->Resize(data->GetNumberOfTuples() - 1);
      }
    }
}

//
// Column functions
//

//----------------------------------------------------------------------------
vtkIdType vtkTable::GetNumberOfColumns()
{
342
  return this->RowData->GetNumberOfArrays();
343
344
345
346
347
}

//----------------------------------------------------------------------------
void vtkTable::AddColumn(vtkAbstractArray* arr)
{
348
349
  if (this->GetNumberOfColumns() > 0 &&
      arr->GetNumberOfTuples() != this->GetNumberOfRows())
350
    {
351
352
353
354
    vtkErrorMacro(<< "Column \"" << arr->GetName() << "\" must have " 
      << this->GetNumberOfRows() << " rows, but has "
      << arr->GetNumberOfTuples() << ".");
    return;
355
    }
356
  this->RowData->AddArray(arr);
357
358
359
360
361
}

//----------------------------------------------------------------------------
void vtkTable::RemoveColumnByName(const char* name)
{
362
  this->RowData->RemoveArray(name);
363
364
365
366
367
368
}

//----------------------------------------------------------------------------
void vtkTable::RemoveColumn(vtkIdType col)
{
  int column = static_cast<int>(col);
369
  this->RowData->RemoveArray(this->RowData->GetArrayName(column));
370
371
372
373
374
375
}

//----------------------------------------------------------------------------
const char* vtkTable::GetColumnName(vtkIdType col)
{
  int column = static_cast<int>(col);
376
  return this->RowData->GetArrayName(column);
377
378
379
380
381
}

//----------------------------------------------------------------------------
vtkAbstractArray* vtkTable::GetColumnByName(const char* name)
{
382
  return this->RowData->GetAbstractArray(name);
383
384
385
386
387
388
}

//----------------------------------------------------------------------------
vtkAbstractArray* vtkTable::GetColumn(vtkIdType col)
{
  int column = static_cast<int>(col);
389
  return this->RowData->GetAbstractArray(column);
390
391
392
393
394
395
396
397
398
}

//
// Table single entry functions
//

//----------------------------------------------------------------------------
void vtkTable::SetValue(vtkIdType row, vtkIdType col, vtkVariant value)
{
399
  vtkAbstractArray* arr = this->GetColumn(col);
400
401
402
403
  if (!arr)
    {
    return;
    }
404
  int comps = arr->GetNumberOfComponents();
405
  if (vtkDataArray::SafeDownCast(arr))
406
407
408
409
    {
    vtkDataArray* data = vtkDataArray::SafeDownCast(arr);
    if (comps == 1)
      {
410
      data->SetVariantValue(row, value);
411
412
413
      }
    else
      {
414
415
      if (value.IsArray() && vtkDataArray::SafeDownCast(value.ToArray()) &&
          value.ToArray()->GetNumberOfComponents() == comps)
416
417
418
419
420
421
422
423
424
425
        {
        data->SetTuple(row, vtkDataArray::SafeDownCast(value.ToArray())->GetTuple(0));
        }
      else
        {
        vtkWarningMacro("Cannot assign this variant type to multi-component data array.");
        return;
        }
      }
    }
426
  else if (vtkStringArray::SafeDownCast(arr))
427
428
429
430
431
432
433
434
    {
    vtkStringArray* data = vtkStringArray::SafeDownCast(arr);
    if (comps == 1)
      {
      data->SetValue(row, value.ToString());
      }
    else
      {
435
436
      if (value.IsArray() && vtkStringArray::SafeDownCast(value.ToArray()) &&
          value.ToArray()->GetNumberOfComponents() == comps)
437
438
439
440
441
442
443
444
445
446
        {
        data->SetTuple(row, 0, vtkStringArray::SafeDownCast(value.ToArray()));
        }
      else
        {
        vtkWarningMacro("Cannot assign this variant type to multi-component string array.");
        return;
        }
      }
    }
447
  else if (vtkVariantArray::SafeDownCast(arr))
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
    {
    vtkVariantArray* data = vtkVariantArray::SafeDownCast(arr);
    if (comps == 1)
      {
      data->SetValue(row, value);
      }
    else
      {
      if (value.IsArray() && value.ToArray()->GetNumberOfComponents() == comps)
        {
        data->SetTuple(row, 0, value.ToArray());
        }
      else
        {
        vtkWarningMacro("Cannot assign this variant type to multi-component string array.");
        return;
        }
      }
    }
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
  else if(vtkUnicodeStringArray::SafeDownCast(arr))
    {
    vtkUnicodeStringArray* data = vtkUnicodeStringArray::SafeDownCast(arr);
    if(comps==1)
      {
      data->SetValue(row, value.ToUnicodeString());      
      }
    else
      {
      if(value.IsArray() && vtkUnicodeStringArray::SafeDownCast(value.ToArray()) &&
         value.ToArray()->GetNumberOfComponents() == comps)
        {
        data->SetTuple(row, 0, vtkUnicodeStringArray::SafeDownCast(value.ToArray()));
        }
      else
        {
        vtkWarningMacro("Cannot assign this variant type to multi-component unicode string array.");
        return;
        }
      }
    }
  else
    {
    vtkWarningMacro("Unable to process array named " << col);
    }
492
493
494
}

//----------------------------------------------------------------------------
495
void vtkTable::SetValueByName(vtkIdType row, const char* col, vtkVariant value)
496
{
497
498
499
500
501
502
503
504
  int colIndex = -1;
  this->RowData->GetAbstractArray(col, colIndex);
  if (colIndex < 0)
    {
    vtkErrorMacro(<< "Could not find column named " << col);
    return;
    }
  this->SetValue(row, colIndex, value);
505
506
}

507
508
509
510
511
512
513
//----------------------------------------------------------------------------
template <typename iterT>
vtkVariant vtkTableGetVariantValue(iterT* it, vtkIdType row)
{
  return vtkVariant(it->GetValue(row));
}

514
//----------------------------------------------------------------------------
515
vtkVariant vtkTable::GetValue(vtkIdType row, vtkIdType col)
516
{
517
  vtkAbstractArray* arr = this->GetColumn(col);
518
519
520
521
522
  if (!arr)
    {
    return vtkVariant();
    }

523
  int comps = arr->GetNumberOfComponents();
524
  if (vtkDataArray::SafeDownCast(arr))
525
526
527
    {
    if (comps == 1)
      {
528
529
530
531
532
533
534
535
536
      vtkArrayIterator* iter = arr->NewIterator();
      vtkVariant v;
      switch(arr->GetDataType())
        {
        vtkArrayIteratorTemplateMacro(
          v = vtkTableGetVariantValue(static_cast<VTK_TT*>(iter), row));
        }
      iter->Delete();
      return v;
537
538
539
540
541
      }
    else
      {
      // Create a variant holding an array of the appropriate type
      // with one tuple.
542
      vtkDataArray* da = vtkDataArray::CreateDataArray(arr->GetDataType());
543
      da->SetNumberOfComponents(comps);
544
      da->InsertNextTuple(row, arr);
545
546
547
548
549
      vtkVariant v(da);
      da->Delete();
      return v;
      }
    }
550
  else if (vtkStringArray::SafeDownCast(arr))
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
    {
    vtkStringArray* data = vtkStringArray::SafeDownCast(arr);
    if (comps == 1)
      {
      return vtkVariant(data->GetValue(row));
      }
    else
      {
      // Create a variant holding a vtkStringArray with one tuple.
      vtkStringArray* sa = vtkStringArray::New();
      sa->SetNumberOfComponents(comps);
      sa->InsertNextTuple(row, data);
      vtkVariant v(sa);
      sa->Delete();
      return v;
      }
    }
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
  else if (vtkUnicodeStringArray::SafeDownCast(arr))
    {
    vtkUnicodeStringArray* data = vtkUnicodeStringArray::SafeDownCast(arr);
    if (comps == 1)
      {
      return vtkVariant(data->GetValue(row));
      }
    else
      {
      // Create a variant holding a vtkStringArray with one tuple.
      vtkUnicodeStringArray* sa = vtkUnicodeStringArray::New();
      sa->SetNumberOfComponents(comps);
      sa->InsertNextTuple(row, data);
      vtkVariant v(sa);
      sa->Delete();
      return v;
      }
    }
586
  else if (vtkVariantArray::SafeDownCast(arr))
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
    {
    vtkVariantArray* data = vtkVariantArray::SafeDownCast(arr);
    if (comps == 1)
      {
      return data->GetValue(row);
      }
    else
      {
      // Create a variant holding a vtkVariantArray with one tuple.
      vtkVariantArray* va = vtkVariantArray::New();
      va->SetNumberOfComponents(comps);
      va->InsertNextTuple(row, data);
      vtkVariant v(va);
      va->Delete();
      return v;
      }
    }
  return vtkVariant();
}

607
608
609
610
611
612
613
614
615
616
617
618
//----------------------------------------------------------------------------
vtkVariant vtkTable::GetValueByName(vtkIdType row, const char* col)
{
  int colIndex = -1;
  this->RowData->GetAbstractArray(col, colIndex);
  if (colIndex < 0)
    {
    return vtkVariant();
    }
  return this->GetValue(row, colIndex);
}

619
620
621
622
623
624
625
626
627
628
629
//----------------------------------------------------------------------------
vtkTable* vtkTable::GetData(vtkInformation* info)
{
  return info? vtkTable::SafeDownCast(info->Get(DATA_OBJECT())) : 0;
}

//----------------------------------------------------------------------------
vtkTable* vtkTable::GetData(vtkInformationVector* v, int i)
{
  return vtkTable::GetData(v->GetInformationObject(i));
}
630

631
//----------------------------------------------------------------------------
632
633
void vtkTable::ShallowCopy(vtkDataObject* src)
{
634
  if (vtkTable* const table = vtkTable::SafeDownCast(src))
635
    {
636
    this->RowData->ShallowCopy(table->RowData);
637
    this->Modified();
638
639
    }

640
  this->Superclass::ShallowCopy(src);
641
}
642

643
644
645
646
647
648
//----------------------------------------------------------------------------
void vtkTable::DeepCopy(vtkDataObject* src)
{
  if (vtkTable* const table = vtkTable::SafeDownCast(src))
    {
    this->RowData->DeepCopy(table->RowData);
649
    this->Modified();
650
651
652
653
    }

  Superclass::DeepCopy(src);
}
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677

//----------------------------------------------------------------------------
vtkFieldData* vtkTable::GetAttributesAsFieldData(int type)
{
  switch(type)
    {
    case ROW:
      return this->GetRowData();
      break;
    }
  return this->Superclass::GetAttributesAsFieldData(type);
}

//----------------------------------------------------------------------------
vtkIdType vtkTable::GetNumberOfElements(int type)
{
  switch (type)
    {
    case ROW:
      return this->GetNumberOfRows();
      break;
    }
  return this->Superclass::GetNumberOfElements(type);;
}